Pointers - stored on the heap or the stack?

Hello all,

I'm still a bit confused on where exactly the pointers are stored when calling for heap and stack. I've searched the web but haven't found an exact answer to my question.

Where does the pointer dp reside?
 
int *dp = new int;


Separate example: where does this pointer of a pointer reside? The new int* pointer resides on the heap but I'm not sure where dpp resides.
 
int **dpp = new int*;


And lastly:

 
int∗∗ ipp=new int∗; ∗ipp=new int; ∗∗ipp=3


Where are these variables stored?

Is ipp in stack and the rest in heap?
It depends.

If you declare a pointer as a local variable inside a function the pointer will be located on the stack.

1
2
3
4
5
int main()
{
	int* p = new int; // p is located on the stack, because it's local variable.
                          // *p is located on the heap, because it was created with new.
}

If the pointer is a member of a class it depends on where the class object is located.

1
2
3
4
5
6
7
8
9
10
struct A
{
	int* p;
};

int main()
{
	A a1;          // a1.p is located on the stack, because a1 is located on the stack.
	A* a2 = new A; // a2->p is located on the heap, because *a2 is located on the heap.
}
Last edited on
How can then one define a new variable from heap? Is that possible or are all "heap" variables began by a pointer?

1
2
int g; //stored in stack
new int d; //not possible...but why? 
Unlike the stack where you can only allocate constant amounts of space, on the heap you can allocate variable amounts of space. For example,
1
2
int *a = new int[a_random_number()];
int *b = new int;
Without the pointer b, how could you locate the right int on the heap?
On the stack it's easy.
1
2
int a[1000]; // Location of a = x
int b; // Location of b = x + sizeof(int) * 1000 
Ah ok. But the pointers b and c are then stored on the stack, right?
If you create an object without using new (or malloc), that object is on the stack. Here are some examples:

1
2
3
int a;
double b;
char* c;


All of these are on the stack.

If you create something with new (or malloc), it is created on the heap. Here are some examples:

1
2
3
4
new int;
new double;
new char;
new char*;


All of these are on the heap (and lost to us forever because we didn't keep track of the pointer to them that the new operator gave back).

Let's see a more practical use of new.

int* p = new int;

On the right there, an int is created? Where? On the heap, because we're creating it with new. On the left there, and int-pointer is created. Where? On the stack, because we're creating it without new.

The pointer p is pointing to memory on the heap, but that's completely irrelevant to where the pointer actually is. The pointer object is on the stack. It's value indicates some memory on the heap, where an int is residing.


- Your Questions -

int **dpp = new int*;
Where does dpp reside? Let's take a look at it. Was dpp created using new? No. So it's on the stack.

int∗∗ ipp=new int∗; ∗ipp=new int; ∗∗ipp=3
Where does ipp reside? Was ipp created using new? No. So it's on the stack.

The int* value that ipp is pointing to. Where does that reside? Was it created using new? Yes. So it's on the heap.

∗ipp; what is that? It's what ipp is pointing at. Was it created using new? Yes. So it's on the heap.

*ipp is pointing at something. What it's pointing at; was it created using new? Yes. So it's on the heap.

ipp (stack) points to some unnamed int pointer (heap) points to some unnamed int (heap) of value 3.
Last edited on
Thanks for the nice explanation. So is then **ipp also on the heap? From your logic, it should be on the stack but I'm not sure that it resides on the stack.
When you say "**ipp" are you referring to ipp, which is of type 'int **', or are you referring to the result of performing a double dereference on ipp ((*(*ipp)))?
int∗∗ ipp=new int∗;

You mean the entitity named ipp? That one on the far left? It's on the stack, because it wasn't created using new. ipp is a pointer to a pointer to an int, and it was made without using new, so it's on the stack. What it may or may not point to is irrelevant. The = is making it point to something, and that something happens to be on the heap, but ipp is not on the heap.

On the right we create an int* using new, on the heap, and make ipp point at it. ipp is on the stack. It's pointing at something on the heap.

Or, as Helios asks, do you mean the thing being pointed to by what ipp is pointing to?
Last edited on
int* * ipp = new int*;
has two parts that can be evaluated separately:
1
2
int** ipp;
ipp = new int*;

The first line declares local variable on stack with name ipp.
The second line allocates memory from heap for unnamed int* object.
The new returns the address the heap memory and we store that value into ipp.
The ipp was and is in the stack; assignment does not change that.

1
2
∗ipp = new int;
**ipp = 42;

The *ipp dereferences a pointer to reach pointed to object. The ipp points to int* object in heap. The *ipp is effectively that int* object in the heap.
The **ipp is *(*ipp), i.e. we derefence the pointer *ipp to reach the int object that happens to be in the heap.


Now something different:
1
2
3
4
int** foo = new int*;
int bar = 7;
*foo = &bar;
**foo = 42;
Hey All,

sorry for the late reply, Uni problem sets got the best of my week.

Helios: I meant (*(*ipp)). ipp is on the stack but from what I now know, I would have to guess **ipp would be on the heap since it would be ipp pointing to a heap pointer. (Thanks Repeater for the great clarification)

keskiverto:

The pointer foo is a pointer on the stack, pointing to an unnamed pointer on the heap.
bar is an integer on the stack that holds the object 7.
*foo is a pointer on the heap and it is now pointing to the variable bar that is on the stack.
**foo points to a pointer on the heap and gives this pointer the object 42? Usually we use the Ampersand to give variables objects but perhaps that is different for heap memory.


General questions:

1. I have seen a lot of code where a pointer points to an int in the heap:
int *ipp = new int;

But what is exactly the variable in the heap? Is there a possible way to give the heap memory a variable name such as we do within the stack? Example:
1
2
int x = 5;
int *p =&x;


I can now either change the value of x with x =7 or with *p =7. Is the only way to do so with heap objects is to use pointers?

2. When we create a pointer on the stack, we use: int *p = &x; Meaning, with the Ampersand. But on the heap we just use int *p = new int; Meaning, we only use "new". I'm beginning to think that since we don't use Ampersands for the heap memory, it is a given that we have to use pointers to interact with objects on the heap.

3.
int **ipp = new int*;

ipp is a pointer to an unnamed pointer. How can we actually use the unnamed pointer if it is (excuse the redundancy) unnamed?


---------------------------

I'm looking forward to your responses. Again thank you Repeater, helios, keskiverto, and Peter87 for the clarifications and input.
But what is exactly the variable in the heap?
It's just an arbitrary memory region that has been set aside by the system for the program. "Set aside" means that the program has control over it and the system cannot give it to other programs until the program gives up control over it.


Is there a possible way to give the heap memory a variable name such as we do within the stack? [...] Is the only way to do so with heap objects is to use pointers?
You're thinking about this the wrong way. Variable names are only a convenience for the programmer provided by the language. When the program is actually running they don't exist.
In fact, in pretty much every modern architecture when you do something like
 
int foo = 42;
what's going to happen when the program runs may be
1
2
stack_pointer_register -= sizeof(int);
*(int *)(stack_pointer_register + some_constant) = 42;
In other words, even variables on the stack can't be used without pointers. You always need a pointer, otherwise there would be no way to find things.


When we create a pointer on the stack, we use: int *p = &x; But on the heap we just use int *p = new int;
They're pointers on the stack. The former points to the stack and the latter points to the heap. Neither pointer is on the heap.


I'm beginning to think that since we don't use Ampersands for the heap memory, it is a given that we have to use pointers to interact with objects on the heap.
& is just the address-of operator. You don't need to get any addresses because new already return an address. But you can always do
 
int *p = &*new int;
if you want. It's pointless, but you can do it.


ipp is a pointer to an unnamed pointer. How can we actually use the unnamed pointer if it is (excuse the redundancy) unnamed?
Consider this:
1
2
int *ipp = new int;
*ipp = 0;

1
2
int **ipp = new int *;
*ipp = nullptr;
Other than the types, is there any difference between these two snippets? Why does it surprise you that you can use an unnamed pointer on the heap, but it doesn't suprise you that you can use an unnamed integer on the heap?
Last edited on
Nice explanation helios. I understand now. Thanks again!
Topic archived. No new replies allowed.