NULL Riddle Answer: The Nothing That Can Crash Your Program, Explained
The riddle:
Main kuch nahi hu, par meri wajah se poora program crash ho jaata hai. Bata kya hu?
Answer: NULL, the null pointer. In C17, NULL is a macro for a null pointer constant. Assigning it to a pointer gives that pointer the null value: it points to no object or function. This does not say that the pointer takes zero bytes or that its representation must be all-zero bits.
NULL itself does not crash anything. The error comes when the program tries to read or write through a null pointer as if an object were there. The riddle names the empty marker, but the invalid operation is the real problem. The C examples below use C17.
Pointer map: a zero value is not a null pointer
int value = 0;
int *p = &value;
p --------> [ value: 0 ]
live int object
p != NULL *p == 0
p = NULL;
p --------> no object
p == NULL do not read or write *p
print_value(p)
|
+-- p == NULL --> report absence, return
|
+-- otherwise --> read *p ONLY when
caller supplied a valid
pointer to a live intThis map shows a relationship, not a numeric memory address. Zero can be ordinary data stored in a real object. NULL marks an absent target. The guard handles absence, not every possible pointer error.
Line 1: "Main kuch nahi hu"
"I am nothing." That is exactly what a null pointer says. When we write int *p = NULL; in C, the pointer p holds no valid address. It points to no variable, no array, nothing.
This is useful, not lazy. Functions use NULL to say "no result found". A search that fails can return NULL. A linked list ends with a next pointer set to NULL. Programmers check for NULL to know there is nothing to work with. Other languages have the same idea with different names: Java has null, Python has None, C++ prefers nullptr.
Line 2: "par meri wajah se poora program crash ho jaata hai"
"Because of me, the whole program crashes." The crime happens at the star. Writing *p means "go to the address inside p and read what is there". If p is NULL, there is no valid address to go to. In C, dereferencing a null pointer is undefined behavior: the standard makes no promise about what happens next.
On most real systems the operating system stops the program with a memory fault. Students usually meet this as a sudden crash with no friendly error message. In Java the same idea shows up as a NullPointerException. The value is small; the damage is program-sized. That is why the riddle says the "nothing" can bring down the whole program.
Tiny C proof: watching the crash get caught
This program makes a null pointer and reads through it:
#include <stddef.h>
#include <stdio.h>
int main(void) {
int *p = NULL;
printf("%d\n", *p);
return 0;
}We compiled it with GCC's undefined behavior sanitizer, which checks the program while it runs:
gcc -std=c17 -Wall -Wextra -pedantic -fsanitize=undefined -fno-sanitize-recover=undefined bad.c -o bad
./badActual output, and the program exited with status 1 instead of finishing:
bad.c:5:5: runtime error: load of null pointer of type 'int'Read that line slowly. "Load" means reading a value. "Null pointer of type int" is our p. Line 5 is printf("%d\n", *p);. The sanitizer caught the exact star that caused the crash. Without the sanitizer the behavior is still undefined: it may crash, it may print garbage, and you are not allowed to rely on either.
The fix: check before you use
The standard defense is one honest question: is there really something at this address? Ask it before the star, not after:
#include <stddef.h>
#include <stdio.h>
void print_value(const int *p) {
if (p == NULL) {
puts("No value available");
return;
}
printf("Value: %d\n", *p);
}
int main(void) {
int value = 42;
print_value(NULL);
print_value(&value);
return 0;
}Compiled with the same sanitizer flags, this runs cleanly from start to finish. Actual output:
No value available
Value: 42The first call passes NULL, so the guard returns before dereferencing. The second call passes the address of a live int object, so the read is valid. This guard handles the NULL case; callers must still meet the contract for a valid non-NULL pointer. It does not fix dangling or uninitialized pointers.
NULL, uninitialized and zero: do not mix them up
| Value | What it means | Safe to dereference? |
|---|---|---|
| NULL | Deliberately set to point to nothing | No, undefined behavior |
| Uninitialized pointer | Indeterminate value; do not read it | No; even reading its value can be invalid |
| Address of a real variable | Points to a live, accessible object of the right type | Yes, while that variable is alive |
A null pointer is a value you can test with p == NULL. An uninitialized automatic pointer has an indeterminate value, not a reliably readable random address. Do not read it even to check whether it is NULL. Initialize pointers to NULL or a valid object address. A non-NULL test alone does not prove that an object is still alive or that the pointer is otherwise valid.
Runnable lab: missing result versus a real zero
A search returns the address of a matching array element or NULL when there is no match. find_value requires a valid array of at least n ints when n is greater than zero. NULL is allowed here only when n is zero, because the loop then never accesses the array. The returned address stays usable only while the source array is alive and unchanged in ways that invalidate it.
#include <stddef.h>
#include <stdio.h>
const int *find_value(const int *a, size_t n, int wanted) {
for (size_t i = 0; i < n; ++i) {
if (a[i] == wanted) return &a[i];
}
return NULL;
}
void show_match(const int *p) {
if (p == NULL) {
puts("not found");
return;
}
printf("found: %d\n", *p);
}
int main(void) {
int values[] = {0, 42};
const int *zero = &values[0];
printf("zero object, null pointer? %d\n", zero == NULL);
printf("zero object value: %d\n", *zero);
show_match(find_value(values, 2, 42));
show_match(find_value(values, 2, 7));
show_match(find_value(NULL, 0, 7));
return 0;
}Compile this as lab.c with the same C17 sanitizer flags used above. Tested with GCC 11.4.0; it exits with status 0 and no sanitizer diagnostic.
zero object, null pointer? 0
zero object value: 0
found: 42
not found
not found| Case | Returned or supplied pointer | Safe action |
|---|---|---|
| Object holding 0 | Address of values[0], not NULL | Read 0 from the live int |
| Search for 42 | Address of values[1] | Read and print 42 |
| Search for 7 | NULL | Report not found; no dereference |
| NULL array, n = 0 | NULL result; loop runs zero times | Report not found |
| NULL array, n > 0 | Violates this function's contract | Do not call it this way |
Cost: at most n comparisons, so worst-case O(n) time and O(1) auxiliary space. The returned pointer does not allocate or copy the matching int.
Exam traps and short answers
Is NULL the same as a stored integer zero?
No. An integer constant expression 0 can be a null pointer constant in a pointer context, but a pointer to an int whose value is 0 is an ordinary non-NULL pointer.
Does non-NULL always mean safe?
No. A pointer may be dangling, misaligned or otherwise invalid. The object must still be alive, accessible and of the right type for the operation.
Can I test an uninitialized pointer for NULL?
No. Initialize the pointer before reading or comparing it. A comparison is still a read.
Is NULL the same as NUL?
No. NULL is a null pointer constant macro. NUL names the zero character, written '\0' in C.
Can every function accept NULL?
No. Follow the function's contract. Our print_value accepts it; find_value accepts it only with n = 0. A check in one function does not change another function's requirements.
Is a segmentation fault guaranteed?
No. Undefined behavior has no guaranteed result. The sanitizer diagnostic above is evidence from that instrumented run, not a promise for every build.
Is Python None a C pointer?
No. None is a Python object used to represent absence, not C's NULL pointer value. The analogy is about meaning, not memory representation.
Quick questions and answers
What is the answer to the riddle?
NULL, the null pointer: a pointer that points to nothing.
Does NULL itself crash the program?
No. Dereferencing it does. In C that is undefined behavior; on most systems the program is stopped with a memory fault.
Why keep NULL around if it is dangerous?
Because "no result" is a real answer. Searches, lists and optional values need a way to say "nothing here", and NULL says it in a way we can test.
What is the one-line defense?
Check if (p == NULL) before every use you cannot prove safe.
Practice: In the fixed program, change main to call print_value(NULL); three times and remove the second call. What prints? Answer: "No value available" three times, once per call, and the program exits normally. We compiled and ran this exact version with the same sanitizer flags to confirm.
Try both programs on your machine. For more riddles with tested proofs, read the BUG riddle answer and the Stack riddle answer. For the full coding series, use the DSA series index.
Sources: Clang: UndefinedBehaviorSanitizer; GCC: instrumentation options. The explanation, examples and test runs here are original.; C pointer values; C dereference rules; NULL versus NUL and representation; Python None.
Comments
Post a Comment