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.
Related
I have a problem about pointer and standard library use.
Let's create a new class
class Graph
{
std::vector<Edge> *edge_list;
//another way is
//std::vector<Edge> edge_list;
}
I already thought two reasons why I use pointer:
It's easy to manipulate the memory using new and delete
It can be passed by parameters easily.
However, we can pass by reference if we use vector.Then Reason 2 doesn't count.
So, Is it true if I am not strict with memory allocation, I don't need to use pointer to vector and other std container?
The implementation of std::vector contains 2 pointers:
The beginning of the allocated array
1 element after the end of the allocated array
Essentially, when you declare a vector it has no space allocated in the heap, but as you add elements this changes.
Note that std::vector manages the memory it uses, so there is no need for you to worry about new and delete (unnecessary complexity). As soon as it goes out of scope, it deallocates its memory (stack and heap).
As you said, a vector can be passed very easily by reference, which works the same way as a pointer for machine code, and it's more clear.
Suppose you developed an optimized custom allocator that you want to use with std::vector (for example, for small allocations the custom allocator gets memory from the stack instead of the heap, kind of like std::string's SSO; or it allocates big chunks of memory using e.g. VirtualAlloc on Windows, and then single allocations are carved from inside a chunk just increasing a pointer).
typedef std::vector<T, OptimizedAllocator<T>> OptimizedVector;
How to use it in a context where you are returning a vector from a function, like this?
OptimizedVector DoSomething()
{
OptimizedVector<int>::allocator_type alloc{};
OptimizedVector<int> v{alloc};
// Do stuff...
return v;
}
At the end of the function's scope, the allocator object is destroyed, so the returned vector could contain garbage, right?
An alternative might be to pass the allocator object as a reference to each function as an additional parameter, but that's kind of ugly...
Is there a way to safely "embed" the allocator object in the vector?
How do you solve this problem?
An allocator must be CopyConstructible without exceptions, and afterwards a1 == a2 must hold (meaning they share the same memory pool). I strongly suggest reading this page on the Allocator concept.
std::vector stores a copy of the allocator you give it.
So if you properly implement your allocator to be safe to copy, there will be no problem with your given code.
The allocator is kept by copy as defined by the standard:
n4140 ยง23.2.1 [container.requirements.general]/8
Unless otherwise specified, all containers defined in this clause
obtain memory using an allocator [...] A copy of this allocator is
used for any memory allocation performed [...]
vector is not "otherwise specified".
This also means that your allocator should support copying and probably be a handle for the real allocator if it needs state.
From here:
The container keeps an internal copy of alloc, which is used to allocate and deallocate storage for its elements, and to construct and destroy them (as specified by its allocator_traits).
So, if I'm not wrong, what you're asking for is the default.
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.
I am writing a memory manager in c++. The aim is to allocate a set amount of memory at the start using malloc and then overload new and delete so that it uses that memory. I almost have it working my only problem is how i am keeping track of what is where in the memory.
I created a vector of structs which holds information such as size, location and if it is free or not.
The problem is when i call push_back it attempts to use my overloaded new function. This is where it fails because it can't use my overloaded new until it has pushed back the first structure of information.
Does anyone know how i can resolve this or a better way to keep track of the memory?
Don't overload global operator new!
The easiest and (WARNING; subjective ->) best solution would be to define your own Allocator which you'll use when dealing with allocation on the free-store (aka. heap). All STL containers have support for passing an AllocatorType as a template argument.
Overloading global operator new/operator delete might seem like a neat solution, but I can almost guarantee you that it will cause you troubles as the developing goes by.
Inside this custom made allocator you can keep track of what goes where, but make the internal std::vector (or whatever you'd like to use, a std::map seems more fitting to me) will use the default operator new/operator delete.
How do I create my own allocator?
The link below will lead you to a nice document with information regarding this matter:
stdcxx.apache.org - Building Your Own Allocators (heavily recommended)
Using a custom allocator when required/wanted will make you not run into any chicken and egg problem when trying to allocate memory for the allocator that will allocate memory, but the allocator must have allocated memory to use the allocator methods.. and what will allocate memory for the allocator but the allocator? Well we will need to allocate memory for that allocator and that allocator must have it's own allocator, though that allocator need memory, provided by another allocator?
Maybe I should just get myself a dog instead, they don't lay eggs - right?
create a class and overload new only in this class. you will not have problems with your vector. you will be able to use your own new with ::new A and the normal new with new A
class C
{
public:
void* operator new( size_t n ) ;
// ...
} ;
otherwise, you can use your own operator function rather than overload operator new :
a basic idea of an allocator :
int *i = myGetMem(i); // and myGetMem() allocates sizeof(*i) bytes of memory.
so you will not have problems with using the vector.
in fact, a real memory allocator keeps the information you put on the vector in the memory allocated it self :
you can take an algorithm for getmem/freemem to adapt it to your case. it can be helpfull.
e.g. : i want to allocate 10 bytes, the memory at #1024 contain information about memory allocated and the allocator returns an adress after 1024, maybe #1030 (depending of the information stored) as the start of allocated memory. so the user gets adress 1030 and he has memory between 1030 and 103A.
when calling the deallocator, the information at the beginning is used to correctly free the memory and to put it back in the list of avaible memory.
(the list of availvle memory is stored in popular alorithms in an array of linked lists of free memories organized by size with algorithms to avoid and minimize fragmentation)
this can resolve your need to the vector.
You can create a vector using any custom allocator.
It is declared in the following manner:
std::vector<YourStruct, YourOwnAllocator> memory_allocations;
YourOwnAllocator is going to be a class which will allocate the data needed for the vector bypassing your overloaded operators.
In needs to provide all the methods and typedefs listed here.
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.