MyClass* po = new MyClass();
po->DoSomething();
and
MyClass po;
MyClass* pp = &po;
pp->DoSomething();
can you explain this including what'll happen in the stack and the heap.
The first case is creating using dynamic memory allocation from the heap an instance of type MyClass. When you leave scope, the object pointed to po will still exist in the heap and leave a memory leak if not taken into account.
The second is instantiating an instance of MyClass on the stack. Then you create a pointer to type MyClass pointing to the object on the stack. When you leave scope, po will be destructed and the object pointed to by pp will be invalid.
The difference is the way you allocate memory.
MyClass* po = new MyClass(); allocates memory from heap and returns the pointer. You can access the memory using the given pointer.
MyClass po; allocates the memory on stack. After you leave the scope (when the function returns) you can't access this memory even if you had the pointer.
Related
For instance:
void Func()
{
int* i = new int; // the simplest case
vector<int*> v = new vector<int*>; // another case, not sure if **new** is using correctly here
vector<int*>* vPointer = new vector<int*>;
}
void main()
{
Func();
}
So, if I allocate dynamic memory(by using new operator) for local variables in functions,
Do they live on heap or stack?
when the program exits the function, are they still dangling around on heap or destroyed as function variables?
Can I use new operator on non-pointer types? How to delete (or return back the allocated heap memory) it later?
Thank you!
int i = 3;
this creates an object of type int on the stack. (The C++ standard uses the term "automatic storage", and I'm usually a stickler for proper use of formal terms, but "stack" and "heap" are deeply embedded in programming vocabulary, so "stack" and "heap" are just fine as technical terms).
int *ip = 0;
this creates an object of type int* on the stack. ip holds a null pointer.
int *ip = new int;
this creates an object of type int* on the stack, just like the previous one. It holds a pointer to memory on the heap (see earlier parenthetical; the formal term is "free store"). You know that the memory is on the heap because that's what operator new does.
When you're finished with the heap memory you have to release it:
delete ip;
if you don't delete it and the function that created it returns, the local variable (ip) that held the pointer is gone. The memory has been allocated and it hasn't been freed, so unless you copied the pointer to some place else, you have no way to get at the memory you allocated. That's called a "memory leak".
I am learning C++ in an online class, currently discussing pointers and memory leaks.
In the course it was told that when a function body ends all local variables are destroyed (in reverse order to which they were declared).
What i'm trying to understand is whether this code leaks memory or not:
void function()
{
TestClass *p = new TestClass();
}
As it seems, it does, but i am not sure why the pointer "p" is not being dereferenced to its heap address and the data there is deleted once the function scope exits.
Definitely it will leak memory. when a function body ends all local variables are destroyed indicates to the variables that are created in stack, not heap. If you allocate memory in heap, you have to release it when done.
Another thing is your concept about dereference is wrong. Dereference means using the object pointed by a pointer, not freeing the memory of the pointer, which is called Deallocation
The pointer itself will be destroyed as it is allocated in stack, but the data which p points to will leak. If you write
TestClass tc;
TestClass *p = &tc;
then all the objects will be created in stack and destroyed, but using new forces to use the memory from heap. You have to use delete to release it.
new is used to allocate memory for a C++ class object in heap, the object's constructor is called after the memory is allocated.
The delete operator must be used to deallocate the memory allocated with the new operator, otherwise there is a memory leak.
delete *p;
If I declare a struct such as this one:
struct MyStruct
{
int* nums;
};
MyStruct ms;
ms.nums = new int[4];
Do I need to call delete ms.nums; before exiting my program or will the member variable nums automatically get deallocated because the MyStruct instance ms wasn't declared on the heap?
Yes, you have to delete that.. struct's default destructor won't do that. It will just delete the pointer variable which holds the address of the object and object will be left alone forever.
Better to do the deletion inside the struct's destructor
struct MyStruct
{
int* nums;
public :
~MyStruct()
{
if(nums != NULL)
delete nums;
}
};
The member variable nums (which is a pointer) will get automatically deallocated when ms, the struct containing it, is popped off the stack.
However, the memory pointed to by nums will NOT. You should call delete [] ms.nums; before your program exits.
You always have to call delete to deallocate all the memory that you explicitly allocated using new.
When you allocate memory using new, memory is allocated in heap and the base address of the block is returned back.
Your struct is present in stack which contains a pointer pointing to that base address. When the struct object leaves the scope, the object is deallocated , i.e. the pointer containig the address of allocated heap memory block is gone, but the heap memory itself is still allocated which you can't deallocate now.
You need to call delete if memory allocated and pointer returned to num. Here num is a pointer inside a structure. Memory for num is allocated when you declare structure variable. But memory address which is allocated by new should be un-allocated by calling delete
Memory for the pointer itself will be deallocated when the object is destroyed, as it is for any class member. However, the array it points to won't be deleted - there is no way to know what the pointer points to, whether it was allocated by new or new[] or not dynamically allocated at all, or whether anything else still wants to use it. To avoid memory leaks, you should delete it, with the array form delete [] ms.nums;, once you've finished with it.
Since it's often hard to do this correctly, why not use a library class to manage the array correctly for you?
#include <vector>
struct MyStruct
{
std::vector<int> nums;
};
MyStruct ms;
ms.nums.resize(4);
Now all the memory will be released automatically when ms is destroyed; and the class is correctly copyable and (since C++11) efficiently movable.
The struct is allocated on the stack, which basically is a pointer to an Array. the array is allocated on the heap. Every time you write "new" that means that the allocation is on the heap therefore you need to "delete" it. On the other hand the struct will be remove as soon as you exit the function.
When program exit, OS will free all memory allocated by your program.
On the other hand, if a memory allocation occurs multiple times during the life of the program, then surely it should be released to prevent dangling pointers.
there are quite a few faces for the new operator in c++, but I'm interested in placement new.
Suppose you allocate memory at a specific memory location
int memoryPool[poolSize*sizeof(int)];
int* p = new (mem) int; //allocates memory inside the memoryPool buffer
delete p; //segmentation fault
How can I correctly deallocate memory in this case?
What if instead of built-in type int I would use some class called myClass?
myClass memoryPool[poolSize*sizeof(myClass )];
myClass * p = new (mem) myClass ; //allocates memory inside the memoryPool buffer
delete p; //segmentation fault
Thanks for your help.
In the first case, there's no point in using placement new, since int doesn't have a constructor.
In the second case, it's either pointless (if myClass is trivial) or wrong, since there are already objects in the array.
You use placement new to initialise an object in a block of memory, which must be suitably aligned, and mustn't already contain a (non-trivial) object.
char memory[enough_bytes]; // WARNING: may not be properly aligned.
myClass * c = new (memory) myClass;
Once you've finished with it, you need to destroy the object by calling its destructor:
c->~myClass();
This separates the object's lifetime from that of its memory. You might also have to release the memory at some point, depending on how you allocated it; in this case, it's an automatic array, so it's automatically released when it goes out of scope.
In your case there is no need to deallocate it, your int array will be deallocated once you return from your function. You should only call explicitly your destructor:
p->~myclass();
to keep you buffer correctly aligned use std::aligned_storage, look in here for example:
http://www.cplusplus.com/reference/type_traits/aligned_storage/
Say I've got a class like this:
class Test
{
int x;
SomeClass s;
}
And I instantiate it like this:
Test* t = new Test;
Is x on the stack, or the heap? What about s?
Test a;
Test *t = new Test;
a, and all its members, are on the stack.
The object pointed to by t, and all its members, are on the heap.
The pointer t is on the stack.
Each time you "instantiate" an object/symbol using a new (we are speaking C++ here), a new memory zone will be allocated for this object. If not, it will be put on the "local" memory zone.
The problem is that I have no standard definition for "local" memory zone.
An example
This means that, for example:
struct A
{
A()
{
c = new C() ;
}
B b ;
C * c ;
}
void doSomething()
{
A aa00 ;
A * aa01 = new A() ;
}
The object aa00 is allocated on the stack.
As aa00::b is allocated on a "local" memory according to aa00, aa00::b is allocated inside the memory range allocated by the new aa00 instruction. Thus, aa00::b is also allocated on stack.
But aa00::c is a pointer, allocated with new, so the object designed by aa00::c is on the heap.
Now, the tricky example: aa01 is allocated via a new, and as such, on the heap.
In that case, as aa01::b is allocated on a "local" memory according to aa01, aa01::b is allocated inside the memory range allocated by the new aa01 instruction. Thus, aa01::b is on the heap, "inside" the memory already allocated for aa01.
As aa01::c is a pointer, allocated with new, the object designed by aa01::c is on the heap, in another memory range than the one allocated for aa01.
Conclusion
So, the point of the game is:
1 - What's the "local" memory of the studied object: Stack of Heap?
2 - if the object is allocated through new, then it is outside this local memory, i.e., it is elsewhere on the heap
3 - if the object is allocated "without new", then it is inside the local memory.
4 - If the "local" memory is on the stack, then the object allocated without new is on the stack, too.
5 - If the "local" memory is on the heap, then the object allocated without new is on the heap, too, but still inside the local memory.
Sorry, I have no better vocabulary to express those concepts.
Since you've used new, it's all on the heap, stored [more or less] contiguously in t's memory area.
t is on the stack. The object at *t is on the heap. It contains an int and a SomeClass object next to each other in a unit.
Since you're using new, you're allocating your object on the heap. Consequently, every members of the Test pointed by t are on the heap too.
class MyClass {
int i;
MyInnerClass m;
MyInnerClass *p = new MyInnerClass();
}
MyClass a;
MyClass *b = new MyClass();
a is on the stack; its members a.i and a.m (including any members of a.m) and a.p (the pointer, not the object it points to) are part of it and so also on the stack.
The object pointed to by a.p is on the heap.
The object pointed to by b is on the heap, including all its members; and so is the object pointed to by b.p.