0

so I just had a quick question, I thought originally that code in general executes from top to bottom. So below I have attached an example in C using pointers and would just like someone to explain to me why the output when printing *p1 is 12 my original thought process was that it would print 25. Thank you

int a = 10, *p1, *p2;
p1 = &a;
*p1 = 25;
p2 = p1;
*p2 = 12;
printf("%d", *p1);
5
  • What was your original thought process? How did you come to the conclusion that it would print 25? Commented Oct 18, 2017 at 15:11
  • 2
    @BenjiSzwimer It's nothing to do with the order things are done in - you were right, they're done top-bottom. Commented Oct 18, 2017 at 15:21
  • 2
    It is executed from top to bottom. But with p2 = p1 both pointers point to the same adress with the same value. It does not matter with which pointer do you change the memory. From that line on p1 an p2 always point to the same value. Commented Oct 18, 2017 at 15:22
  • ya I understand now thanks Steve Commented Oct 18, 2017 at 15:23
  • @Benji Szwimer: But it does execute top to bottom! Yet I don't understand how did top to bottom execution lead you to conclude that it would print 25? Commented Oct 18, 2017 at 15:29

5 Answers 5

7

Let's break it down:

int a = 10, *p1, *p2;  // nothing special
p1 = &a;               // p1 now holds the address of a. printf("%d", *p1) would print 10, as it is the current value of a.

// in this point, printf("%d-%d", *p1,a); would print 10-10 (printf("%d",*p2); is UB as p2 is uninitialized)

*p1 = 25;              // remember that p1 = &a, meaning that now a = 25. Basically you changed (the variable) a, using a pointer instead of changing it directly.
p2 = p1;               // p2 now holds the value of p1, meaning it too points to a

// in this point, printf("%d-%d-%d", *p1,*p2,a); would print 25-25-25

*p2 = 12;              // *p2 = 12, and so does *p1, and so does a

// in this point, printf("%d-%d-%d", *p1,*p2,a); would print 12-12-12

 printf("%d", *p1);

You should remember that a is an int that holds an integer value, and p1,p2 are int * that hold the address of an int. After p1 = &a, every change to a would mean that *p1 is changed too, since *p1 is actually *(&a) [which is...a]. After p2 = p1, the same holds for p2.


I thought originally that code in general executes from top to bottom.

Well, it does :)

Sign up to request clarification or add additional context in comments.

Comments

5

Address values used here is totally arbitrary, just for example

int a = 10, *p1, *p2;

the previous line declare one variable of type int (a) and two pointers to int (p1 and p2)

memory after the previous line

address | memory | variable
1050    | 10     | a
1054    | xxx    | p1
1058    | xxx    | p2

p1 = &a; // &a is address of a, ie here, 1050

memory after the previous line

address | memory | variable
1050    | 10     | a
1054    | 1050   | p1 
1058    | xxx    | p2
  • p1 stores "1050"; *p1, ie value stored at address stored inside p1, is 10

*p1 = 25; // *p1 means value stored at address stored inside p1

memory after the previous line

address | memory | variable
1050    | 25     | a
1054    | 1050   | p1 
1058    | xxx    | p2
  • p1 stores "1050"; *p1, ie value stored at address stored inside p1, is now 25

p2 = p1;

memory after the previous line

address | memory | variable
1050    | 25     | a
1054    | 1050   | p1 
1058    | 1050   | p2
  • p1 stores "1050"; *p1, ie value stored at address stored inside p1, is 25
  • copy values stored inside p1 in p2; so p2 points to a, ie stores address "1050"

*p2 = 12;

memory after the previous line

address | memory | variable
1050    | 12     | a
1054    | 1050   | p1  
1058    | 1050   | p2

printf("%d", *p1); // Print value stored at address stored inside p1

What we can see here:

  • p1 and p2 are pointers: they store address of variable
  • & (like in &a): returns address of a variable
  • * in declaration (like in int *p1): declare pointer to a variable (here to a int variable)
  • * in expression (like in *p1 = 25): access to value stored at address stored in pointer

You can see different addresses and values :

printf("address of a: %p\n", &a);
printf("address of p1: %p\n", &p1);
printf("address of p2: %p\n", &p2);

// address stored inside p1 (ie value stored inside p1)
printf("address stored inside p1: %p\n", p1);
// address stored inside p2 (ie value stored inside p2)
printf("address stored inside p2: %p\n", p2);

printf("value of a: %d\n", a);
printf("value pointed by p1: %d\n", *p1);
printf("value pointed by p2: %d\n", *p2);

2 Comments

This is in my opinion the best answer here. These memory diagrams make it clear! Maybe it would be better to remove the comments after => - the diagrams should be clear enough without the text (especially that the text is long-winded and has spelling errors).
BTW when visualizing address values, it's customary to start the addresses at large numbers, like 1000, 1001, 1002 etc so their values won't be confused with data. It's less important here, since data values are large (10, 12 and 25).
4

The output is 12 because p1 and p2 point to the same memory location (the variable a), so when you assign 12 to *p2 it changes the value of a, which p1 also happens to point to.

I hope this helps.

2 Comments

thanks but when it is written *p1=25 doesn't p1 now point the 25 and no longer a?
*pi = 25 changes the value at the address p1 points to (in this case a). It doesn't change the value of p1. That is, it doesn't change p1 to point somewhere else. 25 is just a value and has no address, thus point to 25 doesn't really make sense.
2

Because both p1 and p2 are pointers, and you do this:

p2 = p1;

This means that p2 points to the same place as p1 and vice versa. You subsequently do this:

*p2 = 12;

This sets *p2 to be 12, but because p1 points to the same place as p2, *p1 will also now equal 12;

When the pointers are pointing at the same thing, you've created an alias. You can access the same data through two different names.

Comments

0
*p1 = 25;

If you printed *p1 now, then you'd get 25.

p2 = p1;

Now p2 points to the same location of p1.

*p2 = 12;

Now you write 12 in the integer pointed by p2, which is the same pointed by p1, as per previous p2 = p1 assignment.

So, you modified the integer value pointed by p1. And this explains why printing *p1 now gives you 12:

printf("%d", *p1)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.