std::vector new runs out of memory - c++

I am writing a program in C++ for a embedded platform STM32. I used to use normal arrays but for the first time I am using vectors in it. So far it runs well in the majority of the cases. However in a very few cases I got the error stated in the title eventhough it shouldn't. Would appreciate some help as I run out of ideas.
My situation
The vectors are like this
struct Boundary{
vector<unsigned short> x; //The x coordinates
vector<unsigned short> y; //The y coordinates
};
Everytime I use these vectors I clear them with
boundary0.x.clear();
boundary0.y.clear();
I add elements with the normal push_back
The strange part
Sometimes, the program finishes with the "Operator new out of memory" when adding elements to the vector.
"!Ah, you run out of memory!"- you would say, but that is the strange part. The vector so far has only 275 elements which being short gives 550 bytes.
But this very same program has handled the same vector with many more elements (500 or more) without problem.
Somehow, you previously leaked out memory!- can be said, and I suspect that. Perhaps I used this before and failed to clean it up (although I cleaned it as I stated) but this error appears even when I disconnect and connect the processor wiping out any previous used memory.
I am at lost why this could be happening. Any help or comment or advice greatly appreciated.

What you need is to reduce vector capacity to its size after vector has been used and clear was performed.
C++11 solution:
Use shrink_to_fit() after clear() function to release memory allocated previously.
boundary0.x.clear();
boundary0.x.shrink_to_fit();
boundary0.y.clear();
boundary0.y.shrink_to_fit();
It will reduce capacity of vector to be equal to its size which after clear() equals to zero.
Note, that shrink_to_fit introduced since C++11.
C++03 and earlier:
'Swap-to-fit' idiom can be used to have same as shrink_to_fit effect.
std::vector<T>(my_vector.begin(), my_vector.end()).swap(my_vector);
will reduce my_vector capacity to its size.
This idiom is described here with detailed explanation how exactly it works: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Shrink-to-fit

When adding an element to a vector using Vector::push_back and the number of elements reach its initial capacity, then the internally reserved buffer will be reallocated (i.e. the existing one might be freed and a larger chunk of memory is allocated). This might "fragment" your memory, as smaller chunks of free memory get available yet the system requires larger chunks, which at some point it might not find any more if the system has rather low memory). Hence, if you do this very often with a lot of vectors, it could get a problem on an embedded system.
Hard to say if this is actually the reason - but I'd try to initialize the vector with a capacity that it will most likely not overreach. Maybe that solves your problem. So you could try out:
struct Boundary{
vector<unsigned short> x = vector<unsigned short>(500); //The x coordinates
vector<unsigned short> y = vector<unsigned short>(500); //The y coordinates
};

Related

Visual C++ vector erase increases memory usage?

it's my very first question here on stackoverflow. I have largely looked for a reason for what I'm experiencing with the following lines of code:
unsigned long long _mem1= getUsedVirtualMemory();
vector.erase(vector.begin() + _idx);
contained= false; // don't stop the loop
_idx--; // the removed object has redefined the idx to be consider.
_mem1 = getUsedVirtualMemory() - _mem1;
if (_mem1 > 0) printf("Memory - 2 mem1: %lu\n" , _mem1);
I have a huge memory consumption in my program and after an intensive debug session, some printfs and time consuming analyses, I arrived to this point:
getUsedVirtualMemory is implemented with the following code:
PROCESS_MEMORY_COUNTERS_EX pmc;
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmc, sizeof(pmc));
SIZE_T virtualMemUsedByMe = pmc.PrivateUsage;
return virtualMemUsedByMe;
to obtain the amount of virtual memory allocated by the process; the vector is a vector of objects (not pointers).
In most cases the vector's erase method seems to work as expected, but in some cases it looks like the erase method of that vector increases the memory used by the process instead of freeing it. I'm using the Windows system function GetProcessMemoryInfo in a lot of situations around the code to debug this problem and it seems to return an actual value for used virtual memory.
I'm using Visual Studio C++ 2010 Professional.
Let me know if more information are needed.
Thanks for any replies.
UPDATE:
Everything you wrote in your replies is correct and I forgot the following details:
I already know that a vector has a size (actual number of elements) and a capacity (allocated slots to store elements)
I already know that the erase method does not free memory (I looked for a lot of documentation about that method)
finally, I will add other elements to that vector later, so I don't need to shrink that vector.
The actual problem is that in that case, the value of "_mem1" in the last line of code shows a difference of 1.600.000 bytes: unjustified increase of memory, while I expected to be 0 bytes.
Also in the case where the value of used memory after the operation would be less than the first one, I would expect a very big number for what is explained for instance at Is unsigned integer subtraction defined behavior?
Instead of the expected results I get a value greater than 0 but relatively short.
To better understand the incidence of the problem, iterating some thousands of times on that piece of code, unexpectedly allocates about 20 Gb of virtual memory.
A vector has :
a size(), which indicates how many active elements are in the container
a capacity(), which tells how many elements are reserved in memory
erase() changes the size to zero. It does not free memory capactiy allocated.
You can use shrink_to_fit() which makes sure that the capacity is reduced to the size.
Changing the size with resize() or the capacity with reserve(), may increase memory allocated if necessary, but it does not necessarily free memory if the new size/capacity is lower than the existing capacity.
It's because erase will not free memory, it just erases elements. Take a look at Herbs.
To (really) release the memory you could do (from reference link):
The Right Way To "Shrink-To-Fit" a vector or deque
So, can we write code that does shrink a vector "to fit" so that its capacity is just enough to hold the contained elements? Obviously reserve() can't do the job, but fortunately there is indeed a way:
vector<Customer>( c ).swap( c );
// ...now c.capacity() == c.size(), or
// perhaps a little more than c.size()
vector.ersase() is only guaranteed to remove elements from the vector, is is not guaranteed to reduce the size of the underlying array (as that process is rather expensive). IE: It only zeros out data, it doesn't necessarily deallocate it.
If you need to have a vector that is only as large as the elements it contains, try using vector.resize(vector.size())
IIRC in a Debug build on windows, new is actually #defined to be DEBUG_NEW which causes (amongst other things) memory blocks not to be actually freed, but merely marked as 'deleted'.
Do you get the same behaviour with a release build?
One part of the puzzle might be that std::vector cannot delete entries from the underlying memory buffer if they are not at the end of the buffer (which yours aren't), so the kept entries are moved - potentially to an altogether different buffer. Since you're erasing the first element, std::vector is allowed (since the standard states that erase() invalidates all iterators at/after the point of erasure, all of them in your case) to allocate an additional buffer to copy the remaining elements to, and then discard the old buffer after copying. So you may end up with two buffers being in use at the same time, and your memory manager will likely not return the discarded buffer to the operating system, but rather keep the memory around to re-use it in a subsequent allocation. This would explain the memory usage increase for a single one of your loop iterations.

C++ Vector Memory

I'm working on a largish project, and we are having some memory issues now. Vectors have been used for all arrays, and a quick search there seems to be about 2000 member vectors.
Going through the code it seems nobody has ever used a reserve or a swap (were not on C++11 yet for this project).
Are there any tools or techniques I can do to find out how much memory is being lost in these vectors?
use valgrind for debugging memory issues.
http://valgrind.org/docs/manual/ms-manual.html
One fast but dirty trick to see the effect of capacity on memory would be to modify
std::vector (or typedef std::vector to your custom vector type).
Idea is to modify vector to ensure that this custom new vector increases capacity exactly by what is needed instead of doubling it (yes, it will be super slow), and see how memory usage of the application changes when you run it with this custom vector.
While not useful in actually optimizing the code, it at least quickly gives you an idea of how much you can gain by optimizing vectors.
Just add some periodic logging lines that print the vector size, capacity and
sizeof(v) + sizeof(element_type) * v.capacity();
for each of your vectors v (this last will be the exact size of the vector in memory). You could register all your vectors somewhere central to keep this tidy.
Then you can do some analysis by searching through your logfiles - to see which ones are using significant amounts of memory and how the usage varies over time. If it is only peak usage that is high, then you may be able to 'resize' your vectors to get rid of the spare capacity.

Freeze in C++ program using huge vector

I have an issue with a C++ program. I think it's a problem of memory.
In my program i'm used to create some enormous std::vector (i use reserve to allocate some memory). With vector size of 1 000 000, it's ok but if i increase this number (about ten millions), my program will freeze my PC and i can do nothing except waiting for a crash (or end of the program if i'm lucky). My vector contains a structure called Point which contain a vector of double.
I used valgrind to check if there is a memory lack. But no. According to it, there is no problem. Maybe using a vector of objects is not advised ? Or maybe is there some system parameters to check or something ? Or simply, the vector is too big for the computer ?
What do you think about this ?
Disclaimer
Note that this answer assumes a few things about your machine; the exact memory usage and error potential depends on your environment. And of course it is even easier to crash when you don't compute on 2d-Points, but e.g. 4d-points, which are common in computer graphics for example, or even larger Points for other numeric purposes.
About your problem
That's quite a lot of memory to allocate:
#include <iostream>
#include <vector>
struct Point {
std::vector<double> coords;
};
int main () {
std::cout << sizeof(Point) << std::endl;
}
This prints 12, which is the size in bytes of an empty Point. If you have 2-dimensional points, add another 2*sizeof(double)=8 to that per element, i.e. you now have a total of 20 bytes per Point.
With 10s of millions of elements, you request 200s of millions of bytes of data, e.g. for 20 million elements, you request 400 million bytes. While this does not exceed the maximum index into an std::vector, it is possible that the OS does not have that much contiguous memory free for you.
Also, your vectors memory needs to be copied quite often in order to be able to grow. This happens for example when you push_back, so when you already have a 400MiB vector, upon the next push_back you might have your old version of the vector, plus the newly allocated 400MiB*X memory, so you may easily exceed the 1000MiB temporarilly, et cetera.
Optimizations (high level; preferred)
Do you need to actually store the data all time? Can you use a similar algorithm which does not require so much storage? Can you refactor your code so that storage is reduced? Can you core some data out when you know it will take some time until you need it again?
Optimizations (low level)
If you know the number of elements before creating your outer vector, use the std::vector constructor which you can tell an initial size:
vector<Foo> foo(12) // initialize have 12 elements
Of course you can optimize a lot for memory; e.g. if you know you always only have 2d-Points, just have two doubles as members: 20 bytes -> 16 bytes. When you do not really need the precision of double, use float: 16 bytes -> 8 bytes. That's an optimization to $2/5$:
// struct Point { std::vector<double> coords; }; <-- old
struct Point { float x, y; }; // <-- new
If this is still not enough, an ad-hoc solution could be std::deque, or another, non-contiguous container: No temporal memory "doubling" because no resizing needed; also no need for the OS to find you such contiguous block of memory.
You can also use compression mechanisms, or indexed data, or fixed point numbers. But it depends on your exact circumstances.
struct Point { signed char x, y; }; // <-- or even this? examine a proper type
struct Point { short x_index, y_index; };
Without seeing your code, this is just speculation, but I suspect it is in large part due to your attempt to allocate a massive amount of memory that is contiguous. std::vector is guaranteed to be in contiguous memory, so if you try to allocate a large amount of space, the operating system has to try to find a block of memory that large that it can use. This may not be a problem for 2MB, but if you are suddenly trying to allocate 200MB or 2GB of contiguous memory ...
Additionally, anytime you add a new element to the vector and it is forced to resize, all of the existing elements must be copied into the new space allocated. If you have 9 million elements and adding the 9,000,001 element requires a resize, that is 9 million elements that have to be moved. As your vector gets larger, this copy time takes longer.
Try using std::deque instead. It is will basically allocate pages (that will be contiguous), but each page can be allocated wherever it can fit.

Possible memory leak when using a vector of a map of strings C++

I have a pretty complex data object that uses has a map of strings
typedef std::map<std::string, unsigned int> Event;
typedef std::pair<double, Event> EventGroup;
std::vector<EventGroup> eventVector;
This is a program that's always running in the background listening to incoming messages. Every time a new EventGroup comes in, which can have any number of strings in the map, I add it to the vector.
// New data came in
eventVector.push_back(newEventGroup);
Every now and then I'll do an erase on this vector
//Flush some of the data because it's old
// it's been determined that the index to erase at is flushIndex
eventVector.erase(eventVector.begin(), eventVector.begin()+flushIndex);
Typically this tends to be the first 5% of the data.
What I've been noticing is that there seems to be a memory leak. The memory usage starts out around 50 MB... but ends up near 1 GB before it's too slow and crashes. I've heard that it's an expensive operation to do an erase, but could this be the cause of the memory leak? Am I missing some way of freeing up the memory used by the map?
Without knowing what your custom types do or look like (are THEY leaking memory?) it's hard to say. You should note however that erasing elements from a vector does not actually free any memory, it makes the area the vector has already allocated available for different elements added to THAT vector. The vector's reserved space remains the same in other words.
So, if you grow a vector to some million elements, erase 90% of them, and are expecting to get a bunch of memory back you'll be disappointed. The way you can free up memory reserved by a vector (which will NEVER give anything back until it's destroyed) is to do the swap idiom thing:
std::vector<EventGroup>(eventVector).swap(eventVector);
I don't recall the exact specifics of how the copy constructor works here. It should behave exactly the same as if you'd done this:
std::vector<EventGroup>(eventVector.begin(), eventVector.end()).swap(eventVector);
You still have no control over how much space this uses up, but if you've freed a lot of space up and it will remain freed for a long while...this should give some unknown amount of memory back to the system.
Keep in mind that this is an expensive operation (which is why std::vector doesn't just do it for you) so only do it when you need to.

vector reserve c++

I have a very large multidimensional vector that changes in size all the time.
Is there any point to use the vector.reserve() function when I only know a good approximation of the sizes.
So basically I have a vector
A[256*256][x][y]
where x goes from 0 to 50 for every iteration in the program and then back to 0 again. The y values can differ every time, which means that for each of the
[256*256][y] elements the vector y can be of a different size but still smaller than 256;
So to clarify my problem this is what I have:
vector<vector<vector<int>>> A;
for(int i =0;i<256*256;i++){
A.push_back(vector<vector<int>>());
A[i].push_back(vector<int>());
A[i][0].push_back(SOME_VALUE);
}
Add elements to the vector...
A.clear();
And after this I do the same thing again from the top.
When and how should I reserve space for the vectors.
If I have understood this correctly I would save a lot of time if I would use reserve as I change the sizes all the time?
What would be the negative/positive sides of reserving the maximum size my vector can have which would be [256*256][50][256] in some cases.
BTW. I am aware of different Matrix Templates and Boost, but have decided to go with vectors on this one...
EDIT:
I was also wondering how to use the reserve function in multidimensional arrays.
If I only reserve the vector in two dimensions will it then copy the whole thing if I exceed its capacity in the third dimension?
To help with discussion you can consider the following typedefs:
typedef std::vector<int> int_t; // internal vector
typedef std::vector<int_t> mid_t; // intermediate
typedef std::vector<mid_t> ext_t; // external
The cost of growing (vector capacity increase) int_t will only affect the contents of this particular vector and will not affect any other element. The cost of growing mid_t requires copying of all the stored elements in that vector, that is it will require all of the int_t vector, which is quite more costly. The cost of growing ext_t is huge: it will require copying all the elements already stored in the container.
Now, to increase performance, it would be much more important to get the correct ext_t size (it seems fixed 256*256 in your question). Then get the intermediate mid_t size correct so that expensive reallocations are rare.
The amount of memory you are talking about is huge, so you might want to consider less standard ways to solve your problem. The first thing that comes to mind is adding and extra level of indirection. If instead of holding the actual vectors you hold smart pointers into the vectors you can reduce the cost of growing the mid_t and ext_t vectors (if ext_t size is fixed, just use a vector of mid_t). Now, this will imply that code that uses your data structure will be more complex (or better add a wrapper that takes care of the indirections). Each int_t vector will be allocated once in memory and will never move in either mid_t or ext_t reallocations. The cost of reallocating mid_t is proportional to the number of allocated int_t vectors, not the actual number of inserted integers.
using std::tr1::shared_ptr; // or boost::shared_ptr
typedef std::vector<int> int_t;
typedef std::vector< shared_ptr<int_t> > mid_t;
typedef std::vector< shared_ptr<mid_t> > ext_t;
Another thing that you should take into account is that std::vector::clear() does not free the allocated internal space in the vector, only destroys the contained objects and sets the size to 0. That is, calling clear() will never release memory. The pattern for actually releasing the allocated memory in a vector is:
typedef std::vector<...> myvector_type;
myvector_type myvector;
...
myvector.swap( myvector_type() ); // swap with a default constructed vector
Whenever you push a vector into another vector, set the size in the pushed vectors constructor:
A.push_back(vector<vector<int> >( somesize ));
You have a working implementation but are concerned about the performance. If your profiling shows it to be a bottleneck, you can consider using a naked C-style array of integers rather than the vector of vectors of vectors.
See how-do-i-work-with-dynamic-multi-dimensional-arrays-in-c for an example
You can re-use the same allocation each time, reallocing as necessary and eventually keeping it at the high-tide mark of usage.
If indeed the vectors are the bottleneck, performance beyond avoiding the sizing operations on the vectors each loop iteration will likely become dominated by your access pattern into the array. Try to access the highest orders sequentially.
If you know the size of a vector at construction time, pass the size to the c'tor and assign using operator[] instead of push_back. If you're not totally sure about the final size, make a guess (maybe add a little bit more) and use reserve to have the vector reserve enough memory upfront.
What would be the negative/positive sides of reserving the maximum size my vector can have which would be [256*256][50][256] in some cases.
Negative side: potential waste of memory. Positive side: less CPU time, less heap fragmentation. It's a memory/cpu tradeoff, the optimum choice depends on your application. If you're not memory-bound (on most consumer machines there's more than enough RAM), consider reserving upfront.
To decide how much memory to reserve, look at the average memory consumption, not at the peak (reserving 256*256*50*256 is not a good idea unless such dimensions are needed regularly)