In C, must I always initialize my last node pointing to NULL? I generally see this happening in tutorials and in books. But to my understanding, an unitialized pointer holds the same address as a NULL pointer. So why initialize?
6 Answers
But to my understanding, an uninitialized pointer holds the same address as a NULL pointer
It might, by (bad) luck.
In any case reading out an uninitialised pointer invokes undefined behaviour. Whether this would lead to a crash (or any other "strange" behaviour) sooner or later is unknown, as by the nature of undefined behaviour.
However depending on how the memory the pointer variable "lives" in is allocated, the memory might come as "already" initialised, if allocating
- it statically or
- via calling
calloc()
Both methods allocate memory and 0 it out in advance. Which, for most recent systems, is sufficient to have a pointer variable (living inside this memory) carrying the value of NULL.
But please note that there still might be implementations around that use a different bit pattern for NULL than just 0-bits. So to stay 100% portable it is good advice to always initialise with NULL explicitly and not rely on implicitly cleared out memory. And btw, this also helps the potential reader of your sources.
Comments
When you create a pointer without initializing it, let's say
char *ptr;
The memory points to some bytes (depending on your pointer type). Those bytes, may be anything. Like some previous initialized unfreed pointer, or, to some garbage.
Which is not the same as a NULL pointer.
To avoid that, you should take the habit of initializing every of your pointers (except for globals and statics which are initialized to 0) and, add a NULL every-time you work with arrays or anything containing multi-elements. Let's say that in this case, NULL is the '\0' of the array/list. For example, if you want to create an array containing a few char *, do it this way :
void function()
{
char *array[4];
array[0] = strdup("Jason");
array[1] = strdup("Mike");
array[2] = strdup("Nicole");
array[3] = NULL;
}
It helps you not to go further than the memory you previously allocated for this pointer, avoiding memory fails, and segmentation faults. In case you're using a counter to get through every case of this array.
Otherwise, don't use NULL everywhere, if you allocated a string, don't fill it with NULL after on.
int main()
{
char *ptr;
if ((ptr = malloc(sizeof(char) * 42)) == NULL)
return (-1);
ptr = NULL;
return (0);
}
This won't work because you're sending NULL into the bytes you cleaned straight before. If you want to properly use a pointer and clean it before using it, you can use memset. Which will send a x amount of the same byte into the pointer, cleaning the garbage that might be in it by the bytes you passed into memset parameters.
6 Comments
'\0' is a null-character - they are not the same thing.You might think that null pointer is the pointer that is uninitialized, but it's wrong. Null pointer is a special pointer which doesn't points to anywhere.
// To declare a null pointer.
int *ptr=NULL;
if(ptr==NULL) //..do something..
Functions like malloc() and getchar() returns null pointer in case they are unable to perforn their task or complete the task.
Comments
Contrary to your understanding, the content of an uninitialized pointer is undefined. Only if the object is statically allocated is it guaranteed to be zero initialised.
5 Comments
malloc doesn't guarantee zero initialisation. Only calloc does.static; it clearly has nothing to do with malloc().statically in the statically allocated. Sorry.0ed memory does not guarantee, that a pointer "living" in there carries the NULL value. Please see footnote 296 here: iso-9899.info/n1570.html#7.22.3.2 (same for floating point variables)
while (p->next) p=p->next.NULLto serve as a sentinel for the end of list. The second type of linked list is a circular linked list where theptr->nextpointer for the last node always holds the address of the start of the list. There no NULL is needed because iteration continues until the first node is reached again. (there are many list types in between) Depending on your requirements one may work better than the other.0xffffffff. Otherwise even comparing it with another pointer is undefined behavior.