There are two problems with this code.
First, printf
expects its first argument to be a format string, and the type of the argument is assumed to be const char *
(it's a pointer to the first character in a zero-terminated string). Since the object p
has type int *
, the expression *p
has type int
, so it's the wrong type, and the value of *p
isn't a valid address of a string, because...
You've initialized p
to NULL
. NULL
is an invalid pointer value that's guaranteed to compare unequal to any valid pointer value (it's a well-defined "nowhere" value). When you write *p
, you're saying, "I want the value of the integer object p
points to." Since p
points "nowhere", the behavior of the operation is undefined, and one possible result of undefined behavior is a segfault.
So...
If you want to print the value of the integer object that p
points to, you would write something like
printf( "%d\n", *p );
but only after you do a sanity check on p
to make sure it isn't NULL
:
if ( p ) // or p != NULL
printf( "%d\n", *p );
Valid pointer values are obtained by one of the following methods:
- Using the unary
&
operator on an lvalue (an expression that refers to an object in memory such that the object may be read or updated):
p = &x; // x is an integer object
p = &a[i]; // a is an array of integer, so a[i] is an integer object
p = &foo.bar; // foo is a struct with an int member named bar, so foo.bar is an integer object
etc.
- Calling one of
malloc
, calloc
, or realloc
:
p = malloc( sizeof *p );
- Using an array expression in most circumstances. Unless it is the operand of the
sizeof
or unary &
operators, or is a string literal being used to intialize a character array in a declaration, an expression of type "N-element array of T
" will be converted ("decay") to an expression of type "pointer to T
", and the value of the expression will be the address of the first element of the array. In the case of printf
, when we write
printf( "this is a test\n" );
the type of the string literal "this is a test\n"
is converted from type "16-element array of char
" to "pointer to char
", and its value is the address of the first character in the string - that address value is what actually gets passed to printf
.