3

Possible Duplicate:
Is NULL always zero in C?

Following code:

char *p1 = 0;
char *p2 = NULL;
char *p3 = (char *)0;

if (NULL == 0)
    printf("the NULL is same as 0\n");

printf("0 : %s\n", 0);
printf("p1 : %s\n", p1);
printf("p1 : %x\n", p1);
printf("&p1 : %x\n", &p1);

printf("NULL : %s\n", NULL);
printf("p2 : %s\n", p2);
printf("p2 : %x\n", p2);
printf("&p2 : %x\n", &p2);
printf("*p2 : %s\n", *p2);

output:

the NULL is same as 0
0 : (null)
p1 : (null)
p1 : 0
&p1 : bf9a0204
NULL : (null)
p2 : (null)
p2 : 0
&p2 : bf9a0208
Segmentation fault (core dumped)

I wonder:

What the (null) stands for?

Does the pointer p1 or p2 point to address 0x0?

Does the statement printf("p1 : %x\n", p1); outputs p1 : 0 indicates p1 point to address 0x0?

Community
  • 1
  • 1
Victor S
  • 4,021
  • 15
  • 43
  • 54
  • Viktor Latypov gave a very good reference about "null", which seems to be the basis of your question: http://en.wikipedia.org/wiki/Null_pointer#Null_pointer. AndreyT is correct: 1) all three of your assignments with "0" are equivalent, and 2) each time you reference NULL (either as a character string, or with "addressof &"), you're causing undefined behavior. – paulsm4 Jul 02 '12 at 18:34
  • @paulsm4 Simply referencing a NULL pointer is not undefined; only dereferencing it is (which is happening when printing with `%s` or explicitly dereferencing it such as `*p2`). Both printing with `%x` and referencing it (`&p1`) are defined. – Aaron Dufour Jul 02 '12 at 18:59
  • @AaronDufour printing with %x is undefined for a different reason: `If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined` (§7.19.6.1/9). %x expects an unsigned int, but the argument is char* and char**. – Cubbi Jul 02 '12 at 19:25
  • @Cubbi I assumed that `%x` means what `%p` since it was spitting out hex. You're right, although I suspect that works as expected in almost all environments. – Aaron Dufour Jul 03 '12 at 14:44

3 Answers3

6

All these initializatiions

char *p1 = 0;
char *p2 = NULL;
char *p3 = (char *)0;

are equivalent. All of them initialize these pointers with null-pointer value of type char *. The physical representation of that null-pointer value is platform-dependent. It is not guaranteed to be represented by physical 0x0 address. There's no way to say what physical address they will "point to" in general.

On your platform null-pointer value happens to be represented by physical address 0x0, judging by the output. However, the proper way to print a pointer value with printf is to either use %p format specifier, or by converting the pointer value to a suitable integral type. Using %x to print pointers leads to undefined behavior.

The (null) output that you see is the reaction of printf to your attempt to use %s specifier with null pointers. This leads to undefined behavior, but your implementation of standard library apparently decided to save your from worse fate and print (null) instead.

In fact, every single printf statement in your code sample is composed incorrectly, each leading to undefined behavior.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
3

What the (null) stands for?

It is how printf() apparently handles the request to print a string when passed a null pointer value. The standard format specifier for pointer values is %p

Does the pointer p1 or p2 point to address 0x0?

Not necessarily. They point at whatever the null pointers point at on your platform.

Does the statement printf("p1 : %x\n", p1); outputs p1 : 0 indicates p1 point to address 0x0?

No, it only indicates that the null pointer value when converted to an unsigned int passed to printf() as a pointer, but reinterpreted as unsigned int (which is what %x expects), results in the value zero. Again, the correct format specifier for pointers is %p.

Cubbi
  • 46,567
  • 13
  • 103
  • 169
  • 3
    I don't think the `(null)` is the result of how the compiler handles printing a null pointer. It's how the implementation of `printf` handles it. It's not determined at compile time, but rather at runtime. – Eran Jul 02 '12 at 18:29
  • @H2CO3 Thanks, that was a good point. – Cubbi Jul 02 '12 at 18:56
  • Just a noob question - `They point at whatever the null pointers point at on your platform.` In this, does the operating system decide it in advance about which memory locations will be represented by `NULL` and ensure that this memory is not allowed to be occupied by anything? – asn Aug 02 '19 at 08:24
  • @Jos I meant the value of a null pointer is not necessarily address zero (can be -1, for example, or something like 0000:FFFF), though most platforms you can find today, the value is indeed all-bits zero. That said, on many systems the memory at address zero is very much allowed to be occupied, though sometimes (e.g. Linux) you need to do some tricks to map and use it (see e.g TUN kernel driver exploit from some years back) – Cubbi Aug 08 '19 at 20:42
0

NULL is usually defined as the numerical value 0, often cast to a pointer type (mostly void *). However, it is not guaranteed by the C standard that the NULL pointer is zero; there are platforms (especially weird old hardware, some embedded systems etc.) where it's another illegal memory address.

It is, however, the case that you can operate with the null pointer as if it always was zero. Writing if (pointer) is converted to if (pointer != NULL); furthermore, when encountering a zero value assigned or compared to a pointer, most compilers treat it as a an operation with NULL in it, even if it's technically non-zero.