But what if you place it in a variable that is not a pointer?
className objectName = new className; |
You wouldn't. In many cases, that would be illegal. It would only be legal if there were some way to convert a pointer (which is, basically, an integer), to an object of type
className. But, even if you'd written such a conversion (by creating a constructor), I can't think of a case where that would ever be useful to do.
new
here returns a pointer, just like in your first example.
Why would you initialise a variable that is not a pointer, and thus on the stack, with an address? |
That bolded part suggests you've misunderstood something. Just because a variable is a pointer, doesn't mean it's not on the stack. Just because a variable is not a pointer, doesn't mean it's on the stack.
A pointer is just a variable like any other. If it's a local variable, it's on the stack. If it's a global variable, or a static variable, it's on the heap.
The value of a pointer is a memory address; i.e. it describes a location in memory. We say the pointer is
pointing to a memory location as a shorthand for that.
That location may be on the stack, or on the heap, or it could be nowhere (if you've set the pointer to
nullptr
or
NULL
or 0), or it could be unknown (if you haven't initialised the pointer).
The crucial thing to remember is that the location of the pointer variable is unrelated to the location of the memory it's pointing to.
So:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
int gI; // gI is a global variable. It is on the heap
int* gPtr; // gPtr is a global variable. It is on the heap
int main()
{
int i = 0; // i is a local variable. It is on the stack.
int *ptr; // ptr is a local variable. It is on the stack.
ptr = &i; // ptr is still on the stack. It is pointing to memory on the stack,
// because i is on the stack.
ptr = &gI; // ptr is still on the stack. It is pointing to memory on the heap,
// because gI is on the heap.
ptr = new int[10]. // ptr is still on the stack. It is pointing to memory on the heap,
// because dynamically allocated memory is on the heap.
gPtr = &i; // gPtr is still on the heap. It is pointing to memory on the stack,
// because i is on the stack.
gPtr = &gI; // gPtr is still on the heap. It is pointing to memory on the heap,
// because gI is on the heap.
gPtr = new int[10]. // gPtr is still on the heap. It is pointing to memory on the
// heap, because dynamically allocated memory is on the heap.
delete[] gPtr ; // Because we always clean up after ourselves.
gPtr = ptr; // gPtr is still on the heap. It is pointing to memory on the
// heap, because it is pointing to the same memory as ptr is pointing to,
// and ptr is pointing to dynamically allocated memory on the heap.
// ptr is still on the stack.
delete ptr; // Note that "delete gPtr" would do exactly the same thing, because
// gPtr and iPtr are pointing to the same memory.
}
|