Reputation: 45921
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.
Upvotes: 7
Views: 18934
Reputation: 96810
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);
Upvotes: 13
Reputation: 45675
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
Upvotes: 10
Reputation: 2310
Your first example
int* max = new int;
*max = 0;
is indeed creating a new int on the heap, and your variable max
saves a pointer to that int. If you're going to use this you're going to have to use delete max;
when you no longer need it to avoid memory leaks.
The second example
int myVar = 20;
int* pVar = &myVar;
is creating a int on the stack, pVar
now is a pointer to the address where the int is saved in the memory. However if you're using this you don't have to delete the pVar
because its not on the heap (you didn't use the new
keyword).
The main difference between the two variables (created on heap and stack) is that the stack variable is going to get deleted automatically when it leaves the scopes. The scope is defined by curly braces {}
:
int* somefnc()
{
int e1
{
int* e2 = new int(0);
int e3 = 0;
} // int e3 gets automatically deleted here
return e2;
} // e1 gets automatically deleted here
// e2 still exists and has to be manually deleted.
One of the advantage of pointers is when dealing with arrays. If you were to make a char array of x elements on the stack you have to know the number of elements at compile time. If you want to make a char array of x elements at runtime with a dynamic number of elements you'd have to use char* ar = new char[x];
and then access it by ar[x-1] = '\n';
.
In order to initialise a variable when creating it on heap you can use var x = new var(args);
.
Upvotes: 1
Reputation: 4245
you can pass the value as argument to initialize the memory in heap.
int *iptr = new int(20);
it is initialized with value 20;
stack: contains local variables. so when you create a pointer and assign it with local objects. its pointing to variables in stack. we are not creating pointer on heap .
Upvotes: 0
Reputation: 2095
Is there a way to create an initialize a pointer with one instruction?
yes:
int * a = new int(20); //initialized with 20;
How can I create a pointer on the stack?
int myVar = 20;
int* pVar = &myVar; //copied your code snipped It's alright
Upvotes: 2