The other answers here are good. Essentially, you can't dereference NULL. I want to also give some intuition for this.
Recall that in C, strings are just sequences of bytes (representing ASCII characters) in memory. We can treat any place in memory (which itself is just one long sequence of bytes) as a string, and we will count the string to be terminated once we hit a byte with value 0 (the character '\0'
).
To drive this point home, let's look at a sample strlen
implementation:
int strlen(char *str) {
int len = -1;
// will evaluate to 0 (false is just 0 in C) when we reach a null terminator.
while (str[++len]);
return len;
}
We start at the address referenced to by str
and keep iterating through memory until we find a 0 value, incrementing the length each time.
Remember NULL is #define
'd to be 0, so when you choose to pass it as a pointer, it references address 0x0
.
First off, your function check_for_NULL
is essentially saying: take a pointer text.
If its address is NULL, return NULL. Otherwise return its address. See how this is extraneous? The function just takes a pointer and spits the same pointer back out.
Now you decide to pass NULL
to check_for_NULL
and print the resultant string. %s
wants to treat its argument as a string, in other words as a char *
, and is going to start dereferencing values from that pointer until it reads a byte with value 0 ("null terminator", char '\0'
). The issue here is this means that the first value printf dereferences is at address 0x0
, which we're not allowed to dereference.
Understand that address 0x0
is not a valid address for us to use. That's the reason we use NULL
pointers to represent errors, invalid values, etc. It's the ideal junk value because it will never not be junk.
A couple of side points:
Compile your programs with the -g flag (for gcc, assuming that's the compiler you're using) to add debugging information. If you do this, valgrind will point at the exact line in your code line where the issue is, which makes debugging much easier.
Don't free() check_NULL
. You use free() on heap pointers, not stack pointers. If you don't understand that yet, just know that unless a pointer was provided to you by malloc()
(or any other alloc
function), it doesn't need to be freed.
Fun little side point: arr[i]
is always equivalent to *(arr + i)
. My Advanced Programming professor called this "the grand unifying theorem of pointers".