51

I've just started learning C and I've been running some simple programs using MinGW for Windows to understand how pointers work. I tried the following:

#include <stdio.h>

int main(){
    int *ptr;
    *ptr = 20;
    printf("%d", *ptr);
    return 0;
}

which compiled properly but when I run the executable it doesn't work - the value isn't printed to the command line, instead I get an error message that says the .exe file has stopped working.

However when I tried storing the value in an int variable and assign *ptr to the memory address of that variable as shown below:

#include <stdio.h>

int main(){
    int *ptr;
    int q = 50;
    ptr = &q;
    printf("%d", *ptr);
    return 0;
}

it works fine.

My question is, why am I unable to directly set a literal value to the pointer? I've looked at tutorials online for pointers and most of them do it the same way as the second example.

Any help is appreciated.

Shreya Srinivas
  • 557
  • 1
  • 6
  • 8
  • Cause that pointer is not initialized - it may point to pretty much anywhere and might crash the program. – Till Jul 15 '13 at 23:50
  • 1
    You got lucky that it terminated with an error. – JonnyRo Jul 15 '13 at 23:55
  • 2
    @JonnyRo is right. In real code, this kind of bug tends to lead to either week-long debugging sessions trying to figure out why some other variable randomly changes every once in a while (never when you're actually testing for it, always when you're doing a public demonstration) or security exploits where someone sets the "is_admin" flag to true by manipulating different values. – abarnert Jul 16 '13 at 00:20
  • The title of this question, "Directly assigning values to C Pointers" is a bit misleading. The whole problem is that you *don't* assign a value to the pointer. – Keith Thompson Sep 27 '15 at 01:32
  • 1
    int *pointer=NULL; Initialize a pointer to null during declaration is a good software engineering practice. – Zeni Jun 24 '22 at 11:47

4 Answers4

93

The problem is that you're not initializing the pointer. You've created a pointer to "anywhere you want"—which could be the address of some other variable, or the middle of your code, or some memory that isn't mapped at all.

You need to create an int variable somewhere in memory for the int * variable to point at.

Your second example does this, but it does other things that aren't relevant here. Here's the simplest thing you need to do:

int main(){
    int variable;
    int *ptr = &variable;
    *ptr = 20;
    printf("%d", *ptr);
    return 0;
}

Here, the int variable isn't initialized—but that's fine, because you're just going to replace whatever value was there with 20. The key is that the pointer is initialized to point to the variable. In fact, you could just allocate some raw memory to point to, if you want:

int main(){
    void *memory = malloc(sizeof(int));
    int *ptr = (int *)memory;
    *ptr = 20;
    printf("%d", *ptr);
    free(memory);
    return 0;
}
abarnert
  • 354,177
  • 51
  • 601
  • 671
32

First Program with comments

#include <stdio.h>

int main(){
    int *ptr;             //Create a pointer that points to random memory address

    *ptr = 20;            //Dereference that pointer, 
                          // and assign a value to random memory address.
                          //Depending on external (not inside your program) state
                          // this will either crash or SILENTLY CORRUPT another 
                          // data structure in your program.  

    printf("%d", *ptr);   //Print contents of same random memory address
                          // May or may not crash, depending on who owns this address

    return 0;             
}

Second Program with comments

#include <stdio.h>

int main(){
    int *ptr;              //Create pointer to random memory address

    int q = 50;            //Create local variable with contents int 50

    ptr = &q;              //Update address targeted by above created pointer to point
                           // to local variable your program properly created

    printf("%d", *ptr);    //Happily print the contents of said local variable (q)
    return 0;
}

The key is you cannot use a pointer until you know it is assigned to an address that you yourself have managed, either by pointing it at another variable you created or to the result of a malloc call.

Using it before is creating code that depends on uninitialized memory which will at best crash but at worst work sometimes, because the random memory address happens to be inside the memory space your program already owns. God help you if it overwrites a data structure you are using elsewhere in your program.

JonnyRo
  • 1,844
  • 1
  • 14
  • 20
3

In the first example, ptr has not been initialized, so it points to an unspecified memory location. When you assign something to this unspecified location, your program blows up.

In the second example, the address is set when you say ptr = &q, so you're OK.

jsp
  • 1,225
  • 11
  • 21
-1

You can set a value for the pointer, but once you've asked for memory for it using "new". This is how your code should look

int main(){
    int *ptr;
    ptr = new int;    //ask for memory
    *ptr = 20;
    printf("%d", *ptr);
    return 0;
}