STL objects in the heap memory?

Started by
6 comments, last by maximAL 16 years, 3 months ago
Hi, I have question that I can not find answer in the documentations of STL; Where do vector and string classes put its own contents into? Why everybody is defining them on stack memory like: (stack) std::vector<ClassA*> vecA; or std::string strA; Why not (heap) std::vector<ClassA*>* pVecA; or std::string* pStrA; ? Does it matter? I think it should be safer memory vise (so that you do not run out of stack space) If someone knows for sure how they work inside please explain.. * I meant contents of itself not contents of what they are pointing to
Advertisement
The contents of various STL structures are already stored on the heap. Declaring the vector (or string, or whatever) on the heap as well is pointless, since a vector is usually only 12 bytes or so (And then the contents will be on the heap).

It's a bit like doing this:
struct container{   ClassA* pData;   size_t nCount;   // push_back() would allocate pData if needed, and add elements to the array};container thing; // On the stack, takes 8 bytes (assuming 32-bit pointers, no padding)container* pThing = new container; // Pointer on the stack (4 bytes [assuming 32-bit pointers], struct contents on the heap (8 bytes)

The data for the ClassA types will be on the heap in either case.
Typically an std::vector<X> will allocate X objects on the heap (technically it's up to the allocator, but that's usually where they end up).

The actual book-keeping member variablesof the vector itself, however, should be declared in automatic storage (which typically means on the stack). By dynamically allocating a vector with the new operator, you place a burden on yourself to clean it up afterwards (with the delete operator). Nobody needs that unless its really necessary.

Similarly, it's more normal to use std::vector<X> rather than std::vector<X*>, unless X is a polymorphic base class, and even then you should consider holding them with a smart-pointer of some kind.
I don't think its that big of a deal, although you're technically right that allocating on the heap would save stack space. The container classes aren't all that big to be honest. I don't know specifically what sizeof(std::vector<T>) would return, but I can't imagine they're very large. The first result page for "sizeof vector" on Google says that at least one implementation implements std::vector in 16 bytes, and that seams reasonable to me for most implimentations (head pointer, tail pointer, plus size and capacity as ints, possibly) but it will vary depending on platform and implimentation. So, that's the same size as a Vec4<float> for instance, or an array of 4 ints. No big deal for the stack.

The standard stack size on Windows defaults to 1 meg, and setting it larger is just a simple option in the compiler/linker settings.

Also, since the stack is already likely cached by the CPU, accessing the vector itself shouldn't cause anything to be flushed out of the cache. If you put it on the heap its possible that it might knock something important out and hurt performance (although unlikely,) but it is certainly another level of indirection each time you hit vector.

Just make it on the stack unless you have a specific case where it causes the stack to overflow and increasing the stack size is not a valid option.

throw table_exception("(? ???)? ? ???");

Thank you for insight; After dealing with very compley container structures during couple last days; like boost containers that hold shared & week pointers, I decided that the main reason why I should leave the container itself in automatic memory is the ease of coding + I did not give a thought previously that containers usually hold only size & pointer variables.
Actually you needn't always save stack space. For example, at least with MingW implementation of std::string, the size of the string and the size of the string pointer are equal (both 4). In fact the string only contains a pointer to a class (struct) that exploits some dark corners of C++ and keeps the size/capacity data and char array together in contiguous memory (if I'm not wrong).

However, the main point of STL containers is that they make memory management automatic. However, if there are no automatic stack objects in your code, only heap-allocated objects, then you are back to square one and have to release memory manually again. (E.g if you allocated a smart pointer with new, you are again responsible for manually deleting it to let it perform its magic.)
If you do not make circular situation (can get around with weak pointers), then shared pointers in boost work like scoped pointers/STL auto pointers. (automatic garbage collection)

I like to use all kinds of smart pointers, makes code look cool (actualy all boost libraries)

BTW, Does anyone know more good libraries than STL, BOOST that developers use to make C++ nicer?
Quote:Original post by the_edd
Typically an std::vector<X> will allocate X objects on the heap (technically it's up to the allocator, but that's usually where they end up).


slightly OT: as far as i understand a custom allocator only manages data storage of the actual content stored by the container but not of internal data like linking-elements in a list etc, right?
------------------------------------------------------------Jawohl, Herr Oberst!

This topic is closed to new replies.

Advertisement