Memory allocation for C++ STL objects - c++

Suppose I am creating an object of STL map in C++ i.e map<string,char>mymap``$. Now, I want to know how memory is being allocated to this object? My point of confusion is that there is no dynamic allocation and we don't know the size of the container in prior. So, from where and how memory is allocated to the object mymap?

there is no dynamic allocation
Sure there is, but it's under the hood. std::map is usually stored as a tree, so a new node is allocated whenever a new object is inserted into it. Dynamically. Just because you don't explicitly write new, it doesn't mean it doesn't happen under the hood.
On the destructor of std::map, the nodes are automatically deleted. Note however that if the nodes contain dynamically allocated objects, those will not be deleted by the map.

So, from where and how memory is allocated to the object mymap?
The default allocator for all Standard containters is std::allocator, from where your container gets memory and releases to when it is done with the memory. You can use custom allocator, and then keep track of all the allocations and deallocations if you want to.

Related

C++ : vector standard template library

In C++ STL vector is a dynamic array, but it performs operations like a stack. So can any one please tell whether data is stored in stack or heap segment.
std::vector itself doesn't define how the memory it uses is allocated. It does memory allocation via an Allocator object.
By default, a vector<T> will use an std::allocator<T> to handle allocation. That, in turn, will use operator new and operator delete to allocate/delete memory.
Those are all subject to change though--the type for the Allocator is passed to vector as a template parameter, so if you want to write an Allocator class that does allocation differently, you're entirely free to do that. Assuming it meets the requirements on an allocator, you can then create instances of std::vector that use your allocator instead of the default one.
You can also provide replacements for operator new and operator delete on a class-by-class and/or global basis. If you do so, std::allocator<T> will use your allocation/deletion routines instead of those defined in the standard library.
It's stores it's elements in a contiguous block on the heap. It can be locally created or dynamically allocated. And finally even a simple c-style array can be used as a stack.
Anything stored in a Vector is stored in contiguous memory in the heap.
It is also not designed to act as a stack, although you could use it to implement stack operations, it is (probably) more effiecient to use an actual stack implementation in that case.*
It is worth noting that the memory used by a Vector can be changed as adding or removing elements can cause it to re-allocate memory.
*If you pre-allocate memory beforehand, then most implementations of a stack will be roughly as efficent as any other.
"
vector<Type> vect;
will allocate the vector, i.e. the header info, on the stack, but the elements on the free store ("heap").
vector<Type> *vect = new vector<Type>;
allocates everything on the free store.
vector<Type*> vect;
will allocate the vector on the stack and a bunch of pointers on the free store, but where these point is determined by how you use them (you could point element 0 to the free store and element 1 to the stack, say)."
Your question is answered by larsmans at 7-11-11.Your welcome.

In C++, is created vector or map in a function on stack or heap?

I just have a very simple question but I can not find it through google.
In C++, if we create a integer in a function, I believe it will be in stack. But if we create a vector or a map, for example,
vector<int> a
will it on stack or heap? I believe that's kind of class object(similar to the object created by "new" in java) so probably it should be on heap?
The vector<int> object itself is created in the storage of your choice: if you declare it as a local variable, that would be in the automatic storage.
However, the vector is usually represented as a pair of pointers; the data for that vector is allocated in the dynamic storage area.
Same goes for std::map<K,V>: the object goes wherever you put it (automatic, static, or dynamic memory, based on your declaration) while the data goes into the dynamic storage area.
Starting with C++11 you can use std::array<T> class for fixed-size collections. The data of this collection will go entirely in the storage where you put the collection itself. However, such collections are not resizable.
The data for any dynamically sized object like that will be heap allocated. If it were on the stack it would risk an overflow and a program crash if it grew too large.
The object itself (i.e. the size of the dynamic array and the pointer to the data's location in memory) will likely be stored on the stack.
Yes this will also be created on the stack.
Variables are only created on the heap when new or malloc is called.
The type doesnt really matter, what matters is how its created.
If you're trying to decide whether or not to create a varaible on the stack or dynamically (on the heap), you should consider the lifetime of the object. If you just need it during the scope that its created in, then create it on the stack. Otherwise create it dynamically.
Here, the vector is stored both on the heap and on the stack. Meaning, the header is on the stack, but as you put elements into the vector, those are dynamically allocated, hence on the heap.

Stack VS Heap with Classes

Say you have a simple class with some storage data structure (list, vector, queue, etc)
class MyClass
{
public:
std::list<OtherClass*> m_myList;
};
Now let's say we allocate this class on the heap.
MyClass* pClass = new MyClass();
Now when we add more items to this list, are they on the heap or on the stack?
Example:
OtherClass* pOtherClass = new OtherClass();
pClass->m_myList.push_front(pOtherClass);
Thanks for the help!
The standard collection classes use an Allocator class to allocate memory for the items being stored. The default allocator will allocate the data on the free store. You can provide your own if you want to, and I suppose if you wanted to badly enough you could have it allocate space on the stack, but you'd have to do a fair amount of extra work to make that happen.
Note that you do not have to allocate the object itself on the free store to make that happen either. In fact, your MyClass *pClass = new MyClass(); is usually a poor idea. You normally just want to use MyClass Class; and be done with it. That will allocate space for the collection object itself (normally quite small) on the stack, but space for what it stores will still normally come from the free store (again, via the allocator). Among other things, this helps automate memory management -- when the collection object goes out of scope, it'll be destroyed. Its destructor will the destroy the objects it contains and release the memory (all automatically).
std::list stores to elements on the heap so it doesn't matter where your class is.
The default allocator for the standard template classes allocate on the heap, no matter what.
So, they would be on the heap.
The simple rule: If you're allocating new OtherClass objects with new, then they are on the heap. new only allocates memory from the heap. (Exception: If you use a custom allocator, which is an advanced C++ feature, they can be in whatever memory area of your choosing.)
Your m_myList is an instance of std::list, which happens to also store its internal information on the heap (but that is an implementation detail and you usually don't need to worry about it).

Splitting QList into chunks, pointers or references?

I have this application that requires me to have a QList which will contain 1 < x < 10000+ objects. Now I have a few issues.
First of all, should I declare the QList as a pointer or straight on the stack? The objects in the QList are pretty small and are wrappers for QFileInfo. But how should I do this?
A list of objects on the stack?
A list (on stack) of pointers to objects on the heap?
A..
QList<FileInfoWrapper>*
Firstly, if I picked solution 2, would my heap be a mess since I just allocate small portions of data all over the place? I dont want that.
Secondly, if I pick the 3rd solution, how would this look in memory when I access the individual objects? And could I create pointers to them (they are afterall on the heap)?
Then we come to my other issue. This list will be past around like a fork at a diner and at some point I would like to create sublists that doesn't hold any data, only references/pointers to some of the objects in the list(for example object 0 to 250). I will then throw these lists into different threads that will have to have a ref to the object to be able to edit them (read: not a hard copy).
Also, could someone explain exactly what happens on the heap when you create a list like this:
QList<FileInfoWrapper>* list = new QList<FileInfoWrapper>();
Would it be like in c where you just create a pointer to the offset where that object will be located?
*(list + sizeof(FileInfoWrapper) * 10)
QList is a container class ... that means that it manages the memory for you so you don't have to worry about it. It's underlying data-structure is a variant of a deque with some special modifications, so your understanding of indexing into the list is not correct. But either way, these are details that are abstracted away by the interface, and you don't need to worry about them. You simply use the given class methods like operator[] or at() to obtain a reference to an object at a given index, and other functions like push_back() or insert() to copy objects into the container. So you can simply make a QList instance on the stack (as long as it doesn't go out-of-scope while it's needed), and copy objects into it. The underlying data-structure will properly allocate the memory needed dynamically to store the objects, and at the time of destruction of the QList object, it will deallocate the memory used to store the objects it "owns".
Think about QList as you would think of a STL container like std::vector or std::list ... again, the underlying data-structure for QList is not the same as these STL containers, but the point is that you can allocate the data-structure on the stack like you would any other class, and it contains all the private data-members and information necessary to manage the memory on the heap. Allocating the QList on the heap through a call to new doesn't gain you anything in that regard ... there are already pointers, etc. inside the data-structure allocating and managing the memory of the contained objects for you.
Finally, don't worry about data-fragmentation. The point of a good container class is to properly allocate memory to avoid memory fragmentation issues from allocating and reallocating memory too often. Additionally, allocating memory takes time, so if a container class were to constantly need to call new, that would really hurt it's performance. While allocating memory on every insertion may be a necessity for node-based containers like linked-lists and trees, hash-tables, dynamic-arrays, and other block-type data-structures are much more efficient at utilizing the memory they allocate to minimize these allocation calls.

About a vector defined in a function

Suppose a std::vector is defined in a function (i.e., on stack) and the vector is re-allocated (like by inserting data). Will any part of the vector be in heap? if yes, will it leave any garbage in heap when done executing the function? Thanks.
Will any part of the vector be in heap?
Yes: all of the elements in a std::vector are stored in a heap-allocated array.
Will it leave any garbage in heap when done executing the function?
No. The std::vector container, like all of the Standard Library containers, is responsible for cleaning up any objects that it creates.
Note, however, that if you dynamically allocate objects (e.g., using new) and store them in a container, then you are responsible for destroying those objects. To avoid having to clean things up yourself, you should avoid explicitly dynamically allocating objects wherever possible and use smart pointers everywhere else.