Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a pointer on the Stack

Tags:

c++

I'm learning C++ and I have a question about pointers.

I have this code:

int* max = new int;
*max = 0;

I think, I have created a pointer on the heap (if I'm not right, please, tell me).

One question:

Is there a way to create an initialize a pointer with one instruction? (now, I'm using two instructions).

Another question:

How can I create a pointer on the stack?

I see code like this one:

int myVar = 20;
int* pVar = &myVar;

I think I haven't created a pointer on the stack but I think it is the only way to not create a pointer on the heap.

I'm very very very new on C++ development.

like image 750
VansFannel Avatar asked May 25 '13 13:05

VansFannel


2 Answers

int* max = new int;

The above line creates a pointer on the stack and initializes it with an integer stored on the heap. Whenever new is involved in an expression, it will return a pointer to its dynamically-created operand:

Per Paragraph 5.3.4/2 of the C++11 Standard:

Entities created by a new-expression have dynamic storage duration (3.7.4). [ -- ] If the entity is a non-array object, the new-expression returns a pointer to the object created. If it is an array, the new-expression returns a pointer to the initial element of the array.

int myVar = 20;
int* pVar = &myVar;

In this example, both the pointer and its value is stored on the stack. A new-expression was not involved in the assignment, so nothing is created on the heap in this situation.

If you want to initialize the value of the pointed-to object in one line, you'd have to value-initialize it like so:

int* max = new int(5);

or in C++11 you can use uniform-initialization:

int* max = new int{5};

It is also important that you remember to delete that which you created with new. Since the memory is in dynamic allocation, its lifetime is not dependent by the scope in which it was created. If you forget to delete your program will get a memory leak.

delete max;

And if max was a pointer set to an array created by a new-expression, you'd use delete[]:

delete[] max;

Note: If a pointer was not initialized by a new-expression, then there is no need to delete.

It's typically recommended that you use containers to mangage the memory for you. Something like std::unique_ptr will do. Once its destructor is called, the memory it holds is deleted:

std::unique_ptr<int> max{new int{5}};

In C++14 we have make_unique:

auto max = std::make_unique<int>(5);
like image 96
David G Avatar answered Sep 30 '22 10:09

David G


Pointers are normal variables, which content is a memory address. This memory can be heap memory or stack memory. Don't confuse the pointer with the memory space it points to.

Your first code allocates space on the heap which can hold an int. You store a pointer to that memory on the stack.

Your second code allocates space on the stack which can hold an int. You store a pointer to that memory on the stack.

So both pointers are on the stack, but only the second points to the stack.

In both cases, the type you allocate is a primitive type. Primitive types aren't initialized per default, unless you immediately assign a value to it (your second code), or use the constructor syntax, which also works with heap-allocated values:

int *max = new int(0);

The same syntax can be used in your second code, by the way:

int myVar(20);

In case you're interested: You can also define pointers on the heap. int* is the type of pointers to ints, so just go ahead and allocate such a type on the heap:

new int*();

This expression returns an int**, which you can then store somewhere. Again, you typically store this pointer-to-pointer on the stack:

int **pointerToPointer = new int*();

As with ints, you can initialize an int* in the new-expression to some pointer-to-int (here, the max pointer from above):

int **pointerToPointer = new int*(max);

Now you have two pointers with the same address: max (pointer on the stack) and some pointer on the heap which you point to using pointerToPointer, i.e. the following holds (I dereference `pointerToPointer, which leads to the value stored behind this pointer, which is a pointer to an int):

max == *pointerToPointer
like image 45
leemes Avatar answered Sep 30 '22 11:09

leemes