I am trying to understand inners of double pointer (which is pointer holding another pointer) to form an array of pointers. So, I am trying to run the following code by experimenting on malloc to debugging and see how it works. I am unable to understand what malloc(0)
does in my case, but my code works by outputting "Hello World".
What is the diff between
pToCharsPointers = (char**) malloc(0);
and
pToCharsPointers = (char**) malloc(2 * sizeof(char*));
Please someone clarify what it is doing in my case.
#include <stdio.h>
char **pToCharsPointers;
int main(void)
{
pToCharsPointers = (char**) malloc(0);
char* pToChars = "Hello";
*pToCharsPointers = pToChars;
*(pToCharsPointers + 1)= "World";
printf("%s %s\n", *(pToCharsPointers + 0), *(pToCharsPointers + 1));
return 0;
}
Also, I would really appreciate if you anyone could explain how double pointers works with an example in memory for visualizing as I fail to see myself even though I tried to read about this in many places.
EDIT: Thanks everyone for sharing your answers, and it really helped to understand. I got a valid pointer with malloc(0) when I printed it, and can dereference it also without issues during multiple tries. Wanted to understand why its working. Seems like in my case undefined behavior was actually a expected one.
In your code
(char**) malloc(0);
is wrong for two reasons, like
Passing size as 0 is implementation defined behaviour and the returned pointer cannot be dereferenced. Quoting the manual page,
If size is
0
, thenmalloc()
returns eitherNULL
, or a unique pointer value that can later be successfully passed tofree()
.
Please see this discussion on why not to cast the return value of malloc()
and family in C
..
Any code, attempting to use the returned pointer for a code like yours, will be essentially dereferencing invalid memory which invokes undefined behavior. So, the output/behaviour of your program can neither be predicted nor reasonified.
OTOH, a statement like
pToCharsPointers = malloc(2 * sizeof(char*));
is valid but you ought to check the validity of the returned pointer to ensure malloc()
is success.
I will try to explain:
pToCharsPointers = (char**) malloc(0);
this line will bring to pToCharPointers a pointer that you can't use
but you can't know if an error will come. don't do that!
char* pToChars = "Hello";
*pToCharsPointers = pToChars;
this line will bring *pToCharsPointers to pToChar that pointing to the "Hello".
*(pToCharsPointers + 1)= "World";
this line will write in *(pToCharsPointers + 1), that you can't know to where it is pointing, "World". also, an option to an error but not for sure.
printf("%s %s\n", *(pToCharsPointers + 0), *(pToCharsPointers + 1));
this line will print "Hello Wolrd" if you didn't get any errors yet.
It simply asks to allocate zero bytes. It is up to the implementation of malloc
if it should return a null pointer or not.
Even if it returns a non-null pointer, you can't dereference it since it will automatically be out of bounds. Dereferencing the returned pointer will lead to undefined behavior in both cases.
When you do malloc(2 * sizeof(char*))
you allocate enough space for two pointers to char
.
You forgot to include <stdlib.h>
. Calling malloc()
without a proper definition has undefined behavior. Explicitly casting its return value hides the fact that the compiler may assume it returns an int
value. This cast is necessary in C++, where calling a function without a prior definition is invalid, but it is counter-productive in C.
Regarding your question: allocating a block of size zero can have two possible outcomes, depending on the implementation of your C library:
malloc(0)
can return NULL
, and attempting to store values at this address has undefined behavior.malloc(0)
can return a valid non-null pointer, but this pointer cannot be dereferenced, nor used to store anything as the size of the object it points to is 0
.In both cases, your code has undefined behavior, which may or may not be a crash.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With