This question already has answers here:
What's the point of malloc(0)?
(17 answers)
Closed 8 years ago.
Very simple question, I made the following program :
#include <stdlib.h>
int main(int argc, char ** argv)
{
void * ptr;
ptr = malloc(0);
free(ptr);
}
And it does not segfault on my machine. Is it a portable behaviour of stdlib malloc and free, or am I looking for trouble ?
Edit : What seems non portable is the value returned by malloc. The question is about the malloc(0) + free combination, not the value of ptr.
The behaviour is implementation defined, you will receive either a NULL pointer or an address. Calling free for the received pointer should however not cause a problem since:
free(NULL) is ok, no operation is done
free(address) is ok, if address was received from malloc (or others like calloc etc.)
It's allowed to return NULL, and it's allowed to return a non-NULL pointer
you can't dereference. Both ways are sanctioned by the standard (7.20.3):
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.
Sorry for the trouble, I should have read the man pages :
malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If size is 0, then malloc() returns either NULL, or a
unique pointer value that can later be successfully passed to free().
free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if
free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.
It seems it is true at least for the gnu libc
According to the c standard
7.20.3
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.
Though it might be legal C/C++, it is indicative a bigger problems. I generally call it 'pointer slopiness'.
See "Do not make assumptions about the result of malloc(0) or calloc(0)", https://www.securecoding.cert.org/confluence/display/seccode/VOID+MEMxx-A.+Do+not+make+assumptions+about+the+result+of+malloc%280%29+or+calloc%280%29.
Updated taking into account libt & Pax's comments:
The behaviour of calling malloc(0) is implementation dependant or in other words non-portable and undefined.
Link to CFaq question for more detail.
In my experience, I have seen that malloc (0) returns a pointer which can be freed.
But, this causes SIGSEGV in later malloc() statements.
And this was highly random.
When I added a check, for not to call malloc if size to be allocated is zero, I got rid of this.
So, I would suggest not to allocate memory for size 0.
-Ashutosh
Related
I just saw this code:
artist = (char *) malloc(0);
...and I was wondering why would one do this?
According to the specifications, malloc(0) will return either "a null pointer or a unique pointer that can be successfully passed to free()".
This basically lets you allocate nothing, but still pass the "artist" variable to a call to free() without worry. For practical purposes, it's pretty much the same as doing:
artist = NULL;
The C standard (C17 7.22.3/1) says:
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.
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.
There's an answer elsewhere on this page that begins "malloc(0) will return a valid memory address and whose range will depend on the type of pointer which is being allocated memory". This statement is incorrect (I don't have enough reputation to comment on that answer directly, so can't put this comment directly under there).
Doing malloc(0) will not automatically allocate memory of correct size. The malloc function is unaware of what you're casting its result to. The malloc function relies purely on the size number that you give as its argument. You need to do malloc(sizeof(int)) to get enough storage to hold an int, for example, not 0.
There are a lot of half true answers around here, so here are the hard facts. The man-page for malloc() says:
If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be
successfully passed to free().
That means, there is absolutely no guarantee that the result of malloc(0) is either unique or not NULL. The only guarantee is provided by the definition of free(), again, here is what the man-page says:
If ptr is NULL, no operation is performed.
So, whatever malloc(0) returns, it can safely be passed to free(). But so can a NULL pointer.
Consequently, writing artist = malloc(0); is in no way better than writing artist = NULL;
malloc(0) doesn't make any sense to me, unless the code is relying on behaviour specific to the implementation. If the code is meant to be portable, then it has to account for the fact that a NULL return from malloc(0) isn't a failure. So why not just assign NULL to artist anyway, since that's a valid successful result, and is less code, and won't cause your maintenance programmers to take time figuring it out?
malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO) or malloc(some_variable_which_might_be_zero) perhaps could have their uses, although again you have to take extra care not to treat a NULL return as a failure if the value is 0, but a 0 size is supposed to be OK.
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.
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.
In Windows:
void *p = malloc(0); will allocate a zero-length buffer on the local heap. The pointer returned is a valid heap pointer.
malloc ultimately calls HeapAlloc using the default C runtime heap which then calls RtlAllocateHeap, etc.
free(p); uses HeapFree to free the 0-length buffer on the heap. Not freeing it would result in a memory leak.
To actually answer the question made: there is no reason to do that
malloc(0) will return NULL or a valid pointer which can be rightly passed to free. And though it seems like the memory that it points to is useless or it can't be written to or read from, that is not always true. :)
int *i = malloc(0);
*i = 100;
printf("%d", *i);
We expect a segmentation fault here, but surprisingly, this prints 100! It is because malloc actually asks for a huge chunk of memory when we call malloc for the first time. Every call to malloc after that, uses memory from that big chunk. Only after that huge chunk is over, new memory is asked for.
Use of malloc(0): if you are in a situation where you want subsequent malloc calls to be faster, calling malloc(0) should do it for you (except for edge cases).
Not sure, according to some random malloc source code I found, an input of 0 results in a return value of NULL. So it's a crazy way of setting the artist pointer to NULL.
http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html
Its actually quite useful, and (obviously IMHO), the allowed behavior of returning a NULL pointer is broken. A dynamic pointer is useful not only for what it points at, but also the fact that it's address is unique. Returning NULL removes that second property. All of the embedded mallocs I program (quite frequently in fact) have this behavior.
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.
According to Reed Copsey answer and the man page of malloc , I wrote some examples to test. And I found out malloc(0) will always give it a unique value.
See my example :
char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
puts("Got a null pointer");
else
puts("Got a valid pointer");
The output will be "Got a valid pointer", which means ptr is not null.
Just to correct a false impression here:
artist = (char *) malloc(0); will never ever return NULL; it's not the same as artist = NULL;. Write a simple program and compare artist with NULL. if (artist == NULL) is false and if (artist) is true.
malloc(0) will return a valid memory address and whose range will depend on the type of pointer which is being allocated memory. Also you can assign values to the memory area but this should be in range with the type of pointer being used. You can also free the allocated memory. I will explain this with an example:
int *p=NULL;
p=(int *)malloc(0);
free(p);
The above code will work fine in a gcc compiler on Linux machine. If you have a 32 bit compiler then you can provide values in the integer range, i.e. -2147483648 to 2147483647. Same applies for characters also. Please note that if type of pointer declared is changed then range of values will change regardless of malloc typecast, i.e.
unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);
p will take a value from 0 to 255 of char since it is declared an unsigned int.
This question already has answers here:
What's the point of malloc(0)?
(17 answers)
Closed 4 years ago.
I know that malloc(size_t size) allocates size bytes and returns a pointer to the allocated memory. .
So how come when I allocate zero bytes to the integer pointer p, I am still able to initialize it?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = malloc(0);
*p = 10;
printf("Pointer address is: %p\n", p);
printf("The value of the pointer: %d\n", *p);
return 0;
}
Here is my program output, I was expecting a segmentation fault.
Pointer address is: 0x1ebd260
The value of the pointer: 10
The behavior of malloc(0) is implementation defined, it will either return a pointer or NULL. As per C Standard, you should not use the pointer returned by malloc when requested zero size space1).
Dereferencing the pointer returned by malloc(0) is undefined behavior which includes the program may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.
1) From C Standard#7.22.3p1 [emphasis added]:
1 The order and contiguity of storage allocated by successive calls to the aligned_alloc, calloc, malloc, and realloc functions is unspecified. The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated). The lifetime of an allocated object extends from the allocation until the deallocation. Each such allocation shall yield a pointer to an object disjoint from any other object. The pointer returned points to the start (lowest byte address) of the allocated space. 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.
When you call malloc(0) and write to the returned buffer, you invoke undefined behavior. That means you can't predict how the program will behave. It might crash, it might output strange results, or (as in this case) it may appear to work properly.
Just because the program could crash doesn't mean it will.
In general, C does not prevent you from doing incorrect things.
After int *p = malloc(0);, p has some value. It might be a null pointer, or it might point to one or more bytes of memory. In either case, you should not use it.1 But the C language does not stop you from doing so.
When you execute *p = 10;, the compiler may have generated code to write 10 to the place where p points. p may be pointing at actual writable memory, so the store instruction may execute without failing. And then you have written 10 to a place in memory where you should not. At this point, the C standard no longer specifies what the behavior of your program is—by writing to an inappropriate place, you have broken the model of how C works.
It is also possible your compiler recognizes that *p = 10; is incorrect code in this situation and generates something other than the write to memory described above. A good compiler might give you a warning message for this code, but the compiler is not obligated to do this by the C standard, and it can allow your program to break in other ways.
Footnote
1 If malloc returns a null pointer, you should not write to *p because it is not pointing to an object. If it returns something else, you should not write to *p because C 2018 7.22.3.1 says, for this of malloc(0), “the returned pointer shall not be used to access an object.”
I think it is good idea to look at segmentation fault definition https://en.wikipedia.org/wiki/Segmentation_fault
The following are some typical causes of a segmentation fault:
Attempting to access a nonexistent memory address (outside process's address space)
Attempting to access memory the program does not have rights to (such as kernel structures in process context)
Attempting to write read-only memory (such as code segment)
So in general, access to any address in program's data segment will not lead to seg fault. This approach makes sence as C doesn't have any framework with memory management in it (like C# or Java). So as malloc in this example returns some address (not NULL) it returns it from program's data segment which can be accessed by program.
However if program is complex, such action (*p = 10) may overwrite data belonging to some other variable or object (or even pointer!) and lead to undefined behaviour (including seg fault).
But please take in account, that as described in other answers such program is not best practice and you shouldn't use such approach in production.
This is a source code of malloc() (maybe have a litter difference between kernel versions but concept still like this), It can answer your question:
static void *malloc(int size)
{
void *p;
if (size < 0)
error("Malloc error");
if (!malloc_ptr)
malloc_ptr = free_mem_ptr;
malloc_ptr = (malloc_ptr + 3) & ~3; /* Align */
p = (void *)malloc_ptr;
malloc_ptr += size;
if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
error("Out of memory");
malloc_count++;
return p;
}
When you assigned size is 0, it already gave you a pointer to first address of memory
This question already has answers here:
Why do I get different results when I dereference a pointer after freeing it?
(7 answers)
Closed 9 years ago.
Below is the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p;
p=(int *)malloc(sizeof(int));
*p=5;
printf("Before freeing=%p\n",p);
printf("Value of p=%d\n",*p);
//making it dangling pointer
free(p);
printf("After freeing =%p\n",p);
printf("Value of p=%d\n",*p);
return 0;
}
Below is the output:
Before freeing=0x1485010
Value of p=5
After freeing =0x1485010
Value of p=0
After freeing the pointer, dereferencing gives the output "0"(zero).
Below is another code that also gives '0'
include <stdio.h>
#include <stdlib.h>
int main()
{
int *p;
p=(int *)malloc(sizeof(int));
printf("Before freeing=%p\n",(void *)p);
printf("Value of p=%d\n",*p);
return 0;
}
In this i have not freed the memory , just allocated it , still it gives '0' .
Is it like the default value of every uninitialized pointer is '0'??
why is it so ?
Don't rely on this, it's undefined behaviour. free() doesn't have to set the pointer to zero, this is just what your current implementation is doing for you. If you want to be 100% sure, regardless of your compiler, platform, etc. set your pointer to NULL after freeing it.
This is simply undefined behavior if we look at the C99 draft standard Annex J.2 which covers undefined behavior says:
The behavior is undefined in the following circumstances:
and included the following bullet:
The value of a pointer that refers to space deallocated by a call to the free or
realloc function is used (7.20.3).
Setting a pointer to NULL after free'ing is usually a good idea and you can find a good discussion here on that topic.
Dereferencing an invalid pointer leads to undefined results per spec. It's not guaranteed to fail.
While the answers "it doesn't matter, it is UB" are in general sufficient, one might be curious why the value changes. Curiosity is (IMHO) a valid reason to know the reason of why something happens.
It depends on the memory management which might decide to store addresses of the "next free block" or whatever in a freed memory area.
So what you observe is probably an action of the memory management.
For example, the memory management MIGHT be implemented in that way that it manages two linked lists and an upper pointer. One linked list contains the allocated memory chunks, pointing maybe 8 or 16 bytes before the "really usable" memory, and the other linked list points to the first free chunk, which in turn contains a pointer to the next one. The memory above the upper pointer is considered as free.
If you free the first memory block, the free list pointer points to it, and its first pointer sized data is zeroed, meaning that there is no other freed block. And there is your reason why the memory is zeroed out.
It is nice to know that things like these exist and how they work, but refrain the temptation to make use of that knowledge in production programs. One day they may fall onto your feet...
This question already has answers here:
What happens to memory after free()?
(4 answers)
Closed 9 years ago.
I have this struct type that I malloc for, and after I free it the pointer still points to the data I assigned. Is that just because the pointer is pointing to memory that is free but hasn't been reallocated yet?
#include <stdio.h>
struct S {
int value;
}
int main () {
S *s = malloc(sizeof(struct S));
s->value = 8910;
free(s);
printf("s: %i\n", s->value);
}
Freed memory doesn't belong to you anymore. But that doesn't mean it disappears or gets changed in any way. Why would your program bother? It would be a waste of time. It probably just marks the memory as available for use by subsequent malloc()s, and that's it. Or it might not. Using memory that doesn't belong to you might do anything: return wrong values, crash, return right values, or run a flight simulator game. It's not yours; don't mess with it and you'll never have to worry about what it might do.
The C standard defines the behavior of the free function:
The free function causes the space pointed to by ptr to be
deallocated, that is, made available for further allocation.
which means that a later call to malloc (or something else) might re-use the same memory space.
As soon as a pointer is passed to free(), the object it pointed to reaches the end of its lifetime. Any attempt to refer to the pointed-to object has undefined behavior (i.e., you're no longer allowed to dereference the pointer).
More than that, the value of the pointer itself becomes indeterminate, so any attempt to refer to the pointer value has undefined behavior. Reference: N1570 6.2.4p2:
If an object is referred to outside of its lifetime, the behavior is
undefined. The value of a pointer becomes indeterminate when the
object it points to (or just past) reaches the end of its lifetime.
It's true that free()'s argument is passed by value (like all C function arguments), and so free can't actually modify the pointer. One way to think of it is that the pointer has the "same" value before and after the call, but that value is valid before the call and indeterminate after the call.
It's likely that an attempt to refer to the pointer value, or even to dereference it, will appear to "work". That's one of the many possible symptoms of undefined behavior (and arguably the worst, since it makes it difficult to detect and diagnose the error).
free() just declares, to the language implementation or operating system, that the memory is no longer required. When it is written over is not defined behavior.
I just saw this code:
artist = (char *) malloc(0);
...and I was wondering why would one do this?
According to the specifications, malloc(0) will return either "a null pointer or a unique pointer that can be successfully passed to free()".
This basically lets you allocate nothing, but still pass the "artist" variable to a call to free() without worry. For practical purposes, it's pretty much the same as doing:
artist = NULL;
The C standard (C17 7.22.3/1) says:
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.
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.
There's an answer elsewhere on this page that begins "malloc(0) will return a valid memory address and whose range will depend on the type of pointer which is being allocated memory". This statement is incorrect (I don't have enough reputation to comment on that answer directly, so can't put this comment directly under there).
Doing malloc(0) will not automatically allocate memory of correct size. The malloc function is unaware of what you're casting its result to. The malloc function relies purely on the size number that you give as its argument. You need to do malloc(sizeof(int)) to get enough storage to hold an int, for example, not 0.
There are a lot of half true answers around here, so here are the hard facts. The man-page for malloc() says:
If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be
successfully passed to free().
That means, there is absolutely no guarantee that the result of malloc(0) is either unique or not NULL. The only guarantee is provided by the definition of free(), again, here is what the man-page says:
If ptr is NULL, no operation is performed.
So, whatever malloc(0) returns, it can safely be passed to free(). But so can a NULL pointer.
Consequently, writing artist = malloc(0); is in no way better than writing artist = NULL;
malloc(0) doesn't make any sense to me, unless the code is relying on behaviour specific to the implementation. If the code is meant to be portable, then it has to account for the fact that a NULL return from malloc(0) isn't a failure. So why not just assign NULL to artist anyway, since that's a valid successful result, and is less code, and won't cause your maintenance programmers to take time figuring it out?
malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO) or malloc(some_variable_which_might_be_zero) perhaps could have their uses, although again you have to take extra care not to treat a NULL return as a failure if the value is 0, but a 0 size is supposed to be OK.
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.
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.
In Windows:
void *p = malloc(0); will allocate a zero-length buffer on the local heap. The pointer returned is a valid heap pointer.
malloc ultimately calls HeapAlloc using the default C runtime heap which then calls RtlAllocateHeap, etc.
free(p); uses HeapFree to free the 0-length buffer on the heap. Not freeing it would result in a memory leak.
To actually answer the question made: there is no reason to do that
malloc(0) will return NULL or a valid pointer which can be rightly passed to free. And though it seems like the memory that it points to is useless or it can't be written to or read from, that is not always true. :)
int *i = malloc(0);
*i = 100;
printf("%d", *i);
We expect a segmentation fault here, but surprisingly, this prints 100! It is because malloc actually asks for a huge chunk of memory when we call malloc for the first time. Every call to malloc after that, uses memory from that big chunk. Only after that huge chunk is over, new memory is asked for.
Use of malloc(0): if you are in a situation where you want subsequent malloc calls to be faster, calling malloc(0) should do it for you (except for edge cases).
Not sure, according to some random malloc source code I found, an input of 0 results in a return value of NULL. So it's a crazy way of setting the artist pointer to NULL.
http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html
Its actually quite useful, and (obviously IMHO), the allowed behavior of returning a NULL pointer is broken. A dynamic pointer is useful not only for what it points at, but also the fact that it's address is unique. Returning NULL removes that second property. All of the embedded mallocs I program (quite frequently in fact) have this behavior.
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.
According to Reed Copsey answer and the man page of malloc , I wrote some examples to test. And I found out malloc(0) will always give it a unique value.
See my example :
char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
puts("Got a null pointer");
else
puts("Got a valid pointer");
The output will be "Got a valid pointer", which means ptr is not null.
Just to correct a false impression here:
artist = (char *) malloc(0); will never ever return NULL; it's not the same as artist = NULL;. Write a simple program and compare artist with NULL. if (artist == NULL) is false and if (artist) is true.
malloc(0) will return a valid memory address and whose range will depend on the type of pointer which is being allocated memory. Also you can assign values to the memory area but this should be in range with the type of pointer being used. You can also free the allocated memory. I will explain this with an example:
int *p=NULL;
p=(int *)malloc(0);
free(p);
The above code will work fine in a gcc compiler on Linux machine. If you have a 32 bit compiler then you can provide values in the integer range, i.e. -2147483648 to 2147483647. Same applies for characters also. Please note that if type of pointer declared is changed then range of values will change regardless of malloc typecast, i.e.
unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);
p will take a value from 0 to 255 of char since it is declared an unsigned int.