This is an allocation on the stack:
char inStack[10];
// and
MyStruct cl;
And this should be allocated in the heap:
char* inHeap = new char[10];
// and
MyClass cl = new MyClass();
What if MyClass contains a char test[10] variable? Does this:
MyClass cl = new MyClass()
...mean that the 10 byte long content of MyClass::test is allocated in the heap instead of the stack?
It would be allocated inside the object, so that if the object is on the heap, the array will be on the heap; if the object is on the stack, the array will be on the stack; if the object is in static memory in the executable, the array will be there also.
In C++, members of objects are part of the object itself. If you have the address of the object and it's size, you know that all the members of the class will be somewhere within the range [address, address + size), no matter where in memory that address actually is (heap, stack, etc).
If MyClass has a char test[10] member, it will be allocated the same way the instance of MyClass was allocated.
MyClass mc; //mc.test is on the stack
MyClass * mcp = new MyClass; //mcp->test is on the heap
The proper terms in the language are automatic and dynamic storage, and these make a bit more sense than stack and heap. In particular automatic storage does not imply stack in general, only in local variables in functions, but as you mention, if you are defining a member of a class, automatic storage will be wherever the enclosing object is, which can be the stack, the heap or a static object.
Related
This is my first question on stack overflow. Apologies if this is a "dumb" question, but I'm currently learning C++, and I'm a little confused by something. As I understand it, in the code below, the variable "myVariable" is declared on the heap but instantiated in the constructor on the stack. So where does it "live" - on the heap or the stack?
class MyClass{
int _myVariable;
MyClass(int i){
_myVariable = i;
}
}
The member variable is allocated according to how class is instantiated.
void example() {
MyClass a{17}; // This allocates memory on stack
MyClass *b = new MyClass(17); // This allocates memory on heap
}
"Stack" and "Heap" are implementation details. The C++ standard defines Automatic Storage and Dynamic Storage.
The most common implementations for the storage of variables are stack and heap, respectively.
The new operator makes an object live on the dynamic storage:
MyClass* mc = new MyClass(14);.
Note how we now need to use a pointer to access it.
With automatic storage, we can omit the pointer semantics:
MyClass mc = MyClass(14); // constructs an object on the automatic storage.
The object lifetime is managed - you've guessed - automatically. More precisely until the end of the scope.
With dynamically allocated objects, you have to manage the lifetime of the objects yourself.
There are cases where you can't use automatic storage: Namely polymorphism.
If MyClass is polymorphic (that means, it has virtual functions), you can't put it into the automatic storage since the compiler needs to know the size of an object. Since with polymorphism, the size of the pointed-to object can change at runtime it's not possible to create it on the automatic storage.
MyClass c = MyClass2(); //Object Slicing
c.foo(); // calls MyClass::foo()
MyClass* cc = new MyClass2(); //No Object Slicing
cc->foo(); // calls MyClass2::foo();
There are helper classes that take away the responsibility to clean up your memory:
unique_ptr and shared_ptr (although the latter is used rarely).
In the given code, nothing is allocated, you have a mere class declaration.
It is contradictory (and wrong) that "myVariable" is declared on the heap while instantiated in the constructor on the stack.
A simple constructor like yours does no allocation, it just assigns value upon creation of a class instance. Constructors do not allocate the instance, destructors do not deallocate it.
The allocation being done on the heap or on the stack will depend on how you use the class (as a plain variable or with a pointer).
It depends on where does the object live. If the actual object is on the heap the variable also lives on the heap. If the object lives on the stack the variable also lives on the stack.
Look at this example:
MyClass myObject = MyClass(5); // myObject lives on the stack and thus the variable i for myObject also lives on the stack
MyClass* newObject = new MyClass(5); // newObject is allocated on the heap and the variable i for newObject lives on the heap
delete newObject; // since newObject is created using new we must free the memory after use
Given the following code:
class MyClass
{
public:
char array[10];
};
int main()
{
MyClass *p = new MyClass;
...
}
As far as I understand - new allocates the object on the heap.
But also, the array is allocated on the stack (no new operator).
So, is the array allocated on heap (because the object is at the heap) or on the program stack?
But also, the array is allocated on the stack (no new operator)
No, the array is a member of the object. It's a part of it. If the object is dynamically allocated, then all of its parts are too.
Note I said all of its parts. We can tweak your example:
class MyClass
{
public:
char *p_array;
};
int main()
{
char array[10];
MyClass *p = new MyClass{array};
// Other code
}
Now the object contains a pointer. The pointer, being a member of the object, is dynamically allocated. But the address it holds, is to an object with automatic storage duration (the array).
Now, however, the array is no longer part of the object. That disassociation is what makes the layout you had in mind possible.
What MyClass *p = new MyClass; really means is that you want to allocate sizeof(MyClass) bytes on the heap/free store to store every member of MyClass. The size of a class is based on it's members. array is a member of MyClass and thus because MyClass is allocated on the free store, so is array.
If you create a class in C++ with non-pointer member variables and non-pointer member functions yet you initialize an instance of the class dynamically (using pointers) does memory usage come from the heap or the stack?
Useful info for a project I am working on as I am trying to reduce memory from the stack :).
Any response is greatly appreciated.
Many thanks and happy coding.
If you use operator new for allocating you class, than it is put on the heap. Not matter if member variables are accessed by pointers or not.
class A {
int a;
float* p;
};
A* pa = new A(); // required memory is put on the heap
A a; // required memory is put on the stack
But be careful as not every instance accessed by a pointer may actually be located on the heap. For example:
A a; // all members are on the stack
A* pa = &a; // accessed by pointer, but the contents are still not on the heap!
On the other side a class instance located on the stack may have most of its data on the heap:
class B {
public:
std::vector<int> data; // vector uses heap storage!
B() : data(100000) {}
};
B b; // b is on the stack, but most of the memory used by it is on the heap
If you use 'new' to create an object the object is created in the heap.
for the pointer variable memory will be allocated in stack but when you are using new or malloc then that memory segment will be allocated in heap
I have a the following class:
class CObj {
private:
MyOtherClass _member;
};
and the following code that creates an instance of CObj class:
CObj* obj = new Cobj;
obj is allocated on the heap, but: Are CObj::_member allocated on the heap too? or on the stack?
obj is a pointer allocated "on the stack"; the object obj points to is "on the heap", and, being obj->_member a member (=a part) of such an object, it's on the heap too.
In general, members, being part of the parent object, are allocated wherever their parent is stored.
_member has automatic storage duration - it is allocated where it's owning object is allocated. So, if you create an instance of CObj with dynamic storage duration, like in your example, it will also be allocated in dynamic storage (the heap). If you create an object with automatic storage duration, it will be on the stack.
The problem with such questions is that C++ does not have any concept of stack and heap - it's just storage durations.
When you call new OS allocate as much memory as size of class on heap and call class contructor.
From this you can see that since MyOtherClass is in CObj and CObj holds MyOtherClass , MyOtherClass is also on heap in same space as CObj .
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.