what's the point in malloc(0)?

2018-12-31 20:28发布

Just saw this code:

artist = (char *) malloc(0);

and I was wondering why would one do this?

标签: c malloc
16条回答
与风俱净
2楼-- · 2018-12-31 20:41

The C standard says:

If the space cannot be allocated, a null pointer is returned. If the size of the space requested is zero, the behavior is implementation defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

So, malloc(0) could return NULL or a valid pointer that may not be dereferenced. In either case, it's perfectly valid to call free() on it.

I don't really think malloc(0) has much use, except in cases when malloc(n) is called in a loop for example, and n might be zero.

Looking at the code in the link, I believe that the author had two misconceptions:

  • malloc(0) returns a valid pointer always, and
  • free(0) is bad.

So, he made sure that artist and other variables always had some "valid" value in them. The comment says as much: // these must always point at malloc'd data.

查看更多
弹指情弦暗扣
3楼-- · 2018-12-31 20:42

Here is the analysis after running with valgrind memory check tool.

==16740== Command: ./malloc0
==16740==
p1 = 0x5204040
==16740==
==16740== HEAP SUMMARY:
==16740==     in use at exit: 0 bytes in 0 blocks
==16740==   total heap usage: 2 allocs, 2 frees, 1,024 bytes allocated
==16740==
==16740== All heap blocks were freed -- no leaks are possible

and here's my sample code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
   //int i;
   char *p1;

   p1 = (char *)malloc(0);
   printf("p1 = %p\n", p1);

   free(p1);

   return 0;

}

By default 1024 bytes is allocated. If I increase the size of malloc, the allocated bytes will increase by 1025 and so on.

查看更多
春风洒进眼中
4楼-- · 2018-12-31 20:43

malloc(0) behaviour is implementation specific. The library can return NULL or have the regular malloc behaviour, with no memory allocated. Whatever it does, it must be documented somewhere.

Usually, it returns a pointer that is valid and unique but should NOT be dereferenced. Also note that it CAN consume memory even though it did not actually allocate anything.

It is possible to realloc a non null malloc(0) pointer.

Having a malloc(0) verbatim is not much use though. It's mostly used when a dynamic allocation is zero byte and you didn't care to validate it.

查看更多
后来的你喜欢了谁
5楼-- · 2018-12-31 20:47

Admittedly, I have never seen this before, this is the first time I've seen this syntax, one could say, a classic case of function overkill. In conjunction to Reed's answer, I would like to point out that there is a similar thing, that appears like an overloaded function realloc:

  • foo is non-NULL and size is zero, realloc(foo, size);. When you pass in a non-NULL pointer and size of zero to realloc, realloc behaves as if you’ve called free(…)
  • foo is NULL and size is non-zero and greater than 1, realloc(foo, size);. When you pass in a NULL pointer and size is non-zero, realloc behaves as if you’ve called malloc(…)

Hope this helps, Best regards, Tom.

查看更多
何处买醉
6楼-- · 2018-12-31 20:47

To actually answer the question made: there is no reason to do that

查看更多
看淡一切
7楼-- · 2018-12-31 20:47

Why you shouldn't do this...

Since malloc's return value is implementation dependent, you may get a NULL pointer or some other address back. This can end up creating heap-buffer overflows if error handling code doesn't check both size and returned value, leading to stability issues (crashes) or even worse security issues.

Consider this example, where further accessing memory via returned address will corrupt heap iff size is zero and implementation returns a non NULL value back.

size_t size;

/* Initialize size, possibly by user-controlled input */

int *list = (int *)malloc(size);
if (list == NULL) {
  /* Handle allocation error */
}
else {
  /* Continue processing list */
}

See this Secure Coding page from CERT Coding Standards where I took the example above for further reading.

查看更多
登录 后发表回答