Reputation: 117
I have a Structure defined called Node
.
Now, I do:
Node* temp;
temp = new Node();
temp is a pointer to a Node, which itself is a complex data type.
Question-1: Is memory allocation on heap contiguous?
Question-2: Which block of memory on heap does 'temp' exactly point to? Is it the memory address of the very first data member in the struct Node?
Now, I do:
delete temp;
Question-3: This deallocates the memory. So, does temp point to a garbage value now or does it point to NULL?
Upvotes: 0
Views: 114
Reputation: 57774
The object itself is allocated from contiguous memory. If you mean where from the heap consecutive new
allocate from: there is no way to know. The heap manager is free to do whatever it wants. In the implementations I have investigated, they are peeled from the initial heap consecutively, but after some delete
and free
calls, the free list is searched for a suitable block under one of several algorithms include "first fit", "best fit", etc.
Yes, the pointer is usually to the lowest address element of the allocated class instance. But this is not always true for derived classes, virtual objects, etc.
Yes, delete
deallocates the object, but the pointer is left pointing to the space that was allocated. It is "bad" to dereference the pointer after delete
. If there is any chance of testing it again, it is good practice to set the pointer to NULL
after delete
.
delete temp; temp = NULL;
Upvotes: 2
Reputation: 5102
Question-1: Is memory allocation on heap contiguous?
Yes, you are given a contiguous block. It does not necesarily means that two consecutive allocations will give you consecutive blocks.
Question-2: Which block of memory on heap does 'temp' exactly point to? Is it the memory address of the very first data member in the struct Node?
Not necesarily, depends on how Node is defined and what is the ABI for your platform and compiler.
Question-3: This deallocates the memory. So, does temp point to a garbage value now or does it point to NULL?
Yes, it keeps pointing to the same address (now free, likely to be reallocated eventually) and it is up to you to set it to NULL.
For question-2. Let's try a little experiment:
1) plain struct
#include <iostream>
class A {
public:
int a;
};
int main() {
A *b=new A();
std::cout << std::hex << b << std::endl;
std::cout << std::hex << &(b->a) << std::endl;
}
and the result (compiled with cygwin)
0x800102d0
0x800102d0
So in this case we're fine.
2) Inherited
#include <iostream>
class A {
public:
int a;
};
class B: public A {
public:
int b;
};
int main() {
B *b=new B();
std::cout << std::hex << b << std::endl;
std::cout << std::hex << &(b->b) << std::endl;
std::cout << std::hex << &(b->a) << std::endl;
}
And the result:
0x800102d0
0x800102d4
0x800102d0
So, B* is no longer the pointer to B's first element, but the pointer to A's first element.
3) Virtual classes
#include <iostream>
class A {
public:
virtual ~A() { }
int a;
};
class B: public A {
public:
int b;
};
int main() {
B *b=new B();
std::cout << std::hex << b << std::endl;
std::cout << std::hex << &(b->b) << std::endl;
std::cout << std::hex << &(b->a) << std::endl;
}
and the result
0x800102d0
0x800102d8
0x800102d4
Now the pointer is pointing neither to the first element of A nor the first element of B, but to a control structure.
Upvotes: 3