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.
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, thenew
-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);
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 int
s, 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 int
s, 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With