I am currently learning pointers in c. I have learned that if I do not assign an address to a pointer and try to print the value of the content of the pointer, then the program will not run properly.
#include <stdio.h>
int main()
{
double *q;
printf("Hello World\n");
printf("*q = %lf", *q);
return 0;
}
For example, the code given above will print 'Hello World' and then return something other than 0, ignoring the 2nd printf() function altogether. Here is the output.
However, things get interesting if a null pointer is included in the code.
#include <stdio.h>
int main()
{
double *p = NULL, *q;
printf("Hello World\n");
printf("*q = %lf", *q);
return 0;
}
Now, this is the output. To be honest, this output does not make any sense to me. I was expecting to get the same result as before but clearly that did not happen. How can an inclusion of a null pointer make *q = 0.000000? I am super confused. Please help me understand what is going on here.
Besides, does the output vary from device to device? I have a hunch that devices with Linux OS would yield a different output. My device has Windows 11 as its OS. Is the output different for other Windows (11 or others) users too? And maybe the value 0.000000 is a garbage value? I am kind of curious.
Thanks in advance.
Your first program did not return; it crashed.
You did not initialize q
. In printf("*q = %lf", *q);
, *q
says to load a double
from the location where q
points. Where does q
point? We do not know, because you did not set a value. A variety of things can happen here, including:
q
would have been stored, then it uses that value it loaded as an address to load a double
. That value is loaded for q
could be an address that is not mapped in your process’ memory, so the hardware signals a memory fault, and your process crashes.q
, but it points to an address that is in your process’ memory, but it is not aligned, so the hardware signals an alignment fault, and your process crashes.double
, and prints the resulting value.q
is not initialized, and therefore printf("*q = %lf", *q);
is meaningless, so it marks it as code with undefined behavior and allows its optimizer to prune it from the semantic representation of your program. (This can result in entire portions of your program vanishing from the generated code.)q
is not initialized, and it prints a diagnostic message about that.Which of these, or other things, happens depends on circumstances, including whether optimization in the compiler is enabled, what warnings in the compiler are enabled, where your program happens to be loaded in memory, how the compiler lays out variables in memory, and more. (Unlike some of the comments assert, it is not true that “you can't expect any consistent results.” What you can or cannot expect depends on circumstances. The C standard does not define the behavior, but that does not mean the behavior is not affected by other things you can learn about.)
When you changed the program, you changed some of these factors, such as what happened to be in the memory that the program attempted to load the value of q
from. If you change to run this on Linux instead of Windows, you will change other factors, and so the results may (and likely will) differ from system to system.