5

Program:

int x; int *y; int **z; z = (int **) malloc (sizeof(int *)); y = (int *) malloc (sizeof(int)); x = 1; *z = &x; *y = x; . . . 

Question: What is the difference between:

*z = &x; *y = x; 

From what I understand *z points to the address of x and *y points to x, but for *y to point to x doesn't that require the address of x? I don't really understand what's going on with these two variables.

Edit: I also want to know when do we know when a variable is allocated on the stack or on the heap?

  • Why is x,y, and z allocated on the stack?
  • Why is *y, **y, *z, **z, allocated on the heap?

Finally, does changing *z, change **z?

3
  • "From what I understand ..." You misunderstand. z and y still point to whatever memory block they pointed to when you allocated them. Commented May 12, 2013 at 14:20
  • You shouldn't cast the return value of malloc() in C. This will help identify the bug of not having a prototype for it. Commented May 12, 2013 at 14:22
  • 1
    First and foremost you need to understand that those last two statements are entirely different. The first assigns the address of x to whatever z points to, while the second assigns the value of of x to whatever y points to. If you assign a value then the original and the copy become "disconnected" so that changing one will not change the other. But when you use just the address then the two are joined at the hip -- change one and you change the other. Commented May 12, 2013 at 14:27

2 Answers 2

6

z is a pointer to a pointer (which will typically point to a dynamically allocated array of pointers).

y is a pointer to int. Again, more often than not it'll point to a dynamically allocated array of ints.

So, the *z = &x; is setting the pointer that z refers to to point at x. I.e., z points at a pointer, which (in turn) points to x.

*y = x; is taking the value of x and assigning it to the int pointed to by y.

For things like this, a picture is often helpful. So, our basic definitions give us this:

enter image description here

The we do:

z = (int **) malloc (sizeof(int *)); y = (int *) malloc (sizeof(int)); 

Which gives us this:

enter image description here

Then we do:

*z = &x; *y = x; 

Which gives us this:

enter image description here

In all of these, a dashed line signifies a pointer from one place to another, while the solid line indicates copying a value from one place to another.

We can then consider the long-term differences between them. For example, consider what happens if we add x=2; after all the assignments above.

In this case, *y will still equal 1, because we copied the value 1 from x to *y. **z will equal 2 though, because it's just a pointer to x -- any change in x will be reflected in **z.

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

Comments

2

This line stores the address of variable x in the memory pointed to by z:

*z = &x; 

This line stores the value of x into memory pointed to by y:

*y = x; 

The two assignment statements are unrelated: the second one makes a copy, while the first one does not. If you change the value of x and then retrieve **z, you will see the new value of x; however, retrieving *y would give you back the old value of x (i.e. 1).

1 Comment

Thank you! This makes so much sense!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.