• Advertisement
Sign in to follow this  

class members, stack or heap?

This topic is 2127 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Just a quick questions regarding class members being on the stack or heap.

For example say I have:


Class Foo
{
public:
Foo(int someNum);
private:
int x;
};
Foo::Foo(int someNum)
{
x = someNum;
}


which I then use later in my program:


int main()
{
Foo x(10); //x object is put onto the stack
Foo* y = new Foo(10); //y points to a foo object on heap
return 0;
}


Would the member variables of object pointed to by y be on the stack? or heap? Do I even need to concern myself with this sort of detail?
Thanks.

Share this post


Link to post
Share on other sites
Advertisement

Just a quick questions regarding class members being on the stack or heap.

For example say I have:


Class Foo
{
public:
Foo(int someNum);
private:
int x;
};
Foo::Foo(int someNum)
{
x = someNum;
}


which I then use later in my program:


int main()
{
Foo x(10); //x object is put onto the stack
Foo* y = new Foo(10); //y points to a foo object on heap
return 0;
}


Would the member variables of object pointed to by y be on the stack? or heap? Do I even need to concern myself with this sort of detail?
Thanks.


It will be on the heap. (the only thing that is on the stack is the pointer itself)

Share this post


Link to post
Share on other sites
Basically, if it's new'd, it's on the heap. If it's not, it is on the stack ( unless a global or static ).


It is of some importance, as a) the stack is actually pretty small, often only 1MB in size ( platform dependant ), so if yours is a large datatype, or you have a LOT of whatever you are allocating, a stack overflow isn't hard to cause. On the flipside, something that is on the stack is (generally) more optimizable, as the compiler knows in advanced when it will be disposed. For most practical purposes though, this isn't very important day to day. If in doubt, heap it.

Share this post


Link to post
Share on other sites
When you are dealing with large amounts of data (like classes), you almost always want it on the heap. As previously mentioned, the stack is rather small, and putting a whole bunch of data on it could easily cause it to overflow. The heap, however, is much larger, and therefore better for classes, structs, etc. Just make sure you always deallocate: the stack does that for you, the heap does not.


int main() {
int x = new int;
//Use the variable
delete x; //Deallocate now that your done
return 0;
}

Share this post


Link to post
Share on other sites
Thank you for your responses,

That was my general concern I wasn't sure if I would need to explicitly create member variables on the heap ie. int x = new int(10), or would it happen automatically if the class itself was allocated on the heap. It is clear now thanks!

Share this post


Link to post
Share on other sites
Just to point it out again.. your object IS it's members. You don't have virtual functions that would add invisible overhead, so all your object "physically" consists of is a single int lying around in memory. So it simply wouldn't be possible for the object to be in a different place than its members, because they are the same thing.

Share this post


Link to post
Share on other sites

Basically, if it's new'd, it's on the heap. If it's not, it is on the stack ( unless a global or static ).


It is of some importance, as a) the stack is actually pretty small, often only 1MB in size ( platform dependant ), so if yours is a large datatype, or you have a LOT of whatever you are allocating, a stack overflow isn't hard to cause. On the flipside, something that is on the stack is (generally) more optimizable, as the compiler knows in advanced when it will be disposed. For most practical purposes though, this isn't very important day to day. If in doubt, heap it.

Stack and heap size are actually compile flag dependant, but by default in VSC++ these are set to 1MB.

Share this post


Link to post
Share on other sites

[quote name='Serapth' timestamp='1334627124' post='4931984']
Basically, if it's new'd, it's on the heap. If it's not, it is on the stack ( unless a global or static ).


It is of some importance, as a) the stack is actually pretty small, often only 1MB in size ( platform dependant ), so if yours is a large datatype, or you have a LOT of whatever you are allocating, a stack overflow isn't hard to cause. On the flipside, something that is on the stack is (generally) more optimizable, as the compiler knows in advanced when it will be disposed. For most practical purposes though, this isn't very important day to day. If in doubt, heap it.

Stack and heap size are actually compile flag dependant, but by default in VSC++ these are set to 1MB.
[/quote]


This is true of Windows binaries, but not true of Linux binaries, while on MacOS the default stack is 8MB and can be set at link or at runtime. Of course, each thread you create can have it's own stack, and they can be determined programmatically.

So it really depends on the platform you are running on.

Share this post


Link to post
Share on other sites

int main() {
int x = new int;
//Use the variable
delete x; //Deallocate now that your done
return 0;
}
I just feel the need to point out this is strongly discouraged. Modern C++ is not so easy. Use [font=courier new,courier,monospace]auto_ptr [/font]or everything else ensuring proper release in case of exception. There's no guarantee, in general, the code will reach the [font=courier new,courier,monospace]delete [/font]call. It's also worth noticing OP forgot a pointer declaration: the above code won't compile, but I take for granted that was just a typo.

Share this post


Link to post
Share on other sites
Hey, the answer to your question is fairly easy, just think about how the memory is layed out. When you have a class point and it has two member variables x and y like this:

class point {
public:
float x_;
float y_;
};

than the memory footprint is 8 byte on a 32 bit system. 2*float.

Stack:

int main()
{
point p;
int x = p.x_;
}

First, the stack pointer decrements by 8 byte (sizeof(point)) . When you refer than to x_, the assembly just takes the baseadress of p, inrements it by the offset 8 and puts that address in a register to be able to do the assigment to local x. Than it will decrement back to the old position and do the assignment.

Heap:

int main
{
point *p = new point;

int x = p->x_;

delete p;
}

What happens here is, that in the first line, the compiler will increment the stack pointer by 4 byte (1 * sizeof(point*)). Than new will find us a free address in the heap space (higher memory address space than the stack) will flag it as taken and return the address which gets stored in the 4 bytes from *p.

When we access this thingy now, assembly will look whats written in *p .This process is dereferencing. If there is a valid value it will jump to the memory address which is stored there, will increment by 8 and put the value there in a register. It will than jump back and assign it to x. :-) We could discuss now if heap access is slower than stack access :-)

If there is anything wrong or incorrect i would appreciate it if people could explain better :-)

Note: It will be different when there is a vtable :-)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement