0

I am studying C at school , and I am facing a problem with pointers , Why does this unhandled error rise (im using visual studio 2013 express for desktop on 64 bit windows 10) , when I try to run the code below.

My question is , Why is this happening?

Code Block :

// ~~ Libraries Or Header Files. ~~ //

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ~~ Main Function ~~ //
int main(void)
{
    // ~ Variables ~ //
    int  * p = NULL;//#define NULL ((void *)0)
    printf(*p);
  //printf(p)l also raises an error.



    // ~ END ~ //
    system("PAUSE");
    return 0;
}

Error:

" Unhandled exception at 0x009A3C2A in hwQ3.exe: 0xC0000005: Access violation reading location 0x00000000 ".

Yuval
  • 180
  • 13

3 Answers3

1

The first argument to printf(...) is a const char *format so in both cases you're trying to dereference a NULL pointer. That causes you to access memory outside your allowable range (at zero).

cleblanc
  • 3,678
  • 1
  • 13
  • 16
1

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.
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Basic information about pointers:

Pointers are to declare a pointer variable, set it to point somewhere, and finally manipulate the value that it points to. A simple pointer declaration looks like this:

int *ip;

Pointers are generated with the address-of'' operator &, which we can also think of as thepointer-to'' operator. Demonstrating this by declaring (and initializing) an int variable i, and then setting ip to point to it:

int i = 5;
ip = &i;

Example pointer usage:

#include <stdio.h>

int main(){
    int var =10;
    int *ptr = &var;
    printf("%d\n", *ptr);
    return 0;
}

What happens when you deference the pointer to NULL?

int *a = NULL;  // a is a null pointer
int b = *a;     // CRASH: dereferencing a, trying to read it
*a = 0;         // CRASH: dereferencing b, trying to write it
danglingpointer
  • 4,708
  • 3
  • 24
  • 42
  • Would also be helpful to understand 'what the pointer stores' (an address)... use `%p` for printing a pointer... `printf("%p\n", ptr);` – Attie Mar 24 '17 at 14:03
  • printf("%p\n", ptr); will point to the address which pointer refers, it shows 0x7ffc5625641c in my 64bit machine. Formate specifier %p : print pointer address stored in pointer – danglingpointer Mar 24 '17 at 14:13
  • Correct. `0x7ffc5625641c` is the address of your `var` pointer. – Attie Mar 24 '17 at 14:15