I have a class, let’s call it Builder. It has a private member declared as
vector< vector< Node >> buffers; // Node is a pure data class.
In this Builder class constructor, I do:
buffers = vector< vector< Node >>(amount);
where “amount” is only known at runtime.
During the lifetime of the builder class, several operations get called on the buffers member. The only operations I’m using are:
buffers[i].push_back(Node());
buffers[i].clear();
I’m just adding the meat of the algorithm here for reference:
// REFINE BUFFERS
// check all levels (bottom up) and group 8 nodes on a higher level
for(int d = maxdepth; d >= 0; d--){
if(buffers[d].size() == 8){ // if we have 8 nodes
if(isBufferEmpty(buffers[d])){
buffers[d-1].push_back(Node()); // push back NULL to represent 8 empty nodes
} else {
buffers[d-1].push_back(groupNodes(octree, buffers[d])); // push back parent node
}
buffers[d].clear(); // clear the 8 nodes on this level
} else {
break; // break the for loop: no upper levels will need changing
}
}
When the Builder class object goes out of scope, it gets destroyed, and with it, its class members as well. When I’m in VS2010 debug mode, there is no problem. When in release mode, I get the following error: “Windows has triggered a breakpoint”.
The problem lies within this part of the STL:vector specification, at the _Destroy call.
void _Tidy()
{ // free all storage
if (this->_Myfirst != 0)
{ // something to free, destroy and deallocate it
this->_Orphan_all();
_Destroy(this->_Myfirst, this->_Mylast);
this->_Alval.deallocate(this->_Myfirst,
this->_Myend - this->_Myfirst);
}
this->_Myfirst = 0;
this->_Mylast = 0;
this->_Myend = 0;
}
Looking at the debugger, I can see that _Mylast has an incorrect value (0x000000000000), which is probably what causes this de-allocation to fail. I have the same result when I try to do buffers.clear() at the end. (buffers[i].clear() works fine). Also, when I just hit “continue”, my program works fine as well.
I have some output from my algorithm after it has run. What you see is the amount of elements in the individual vectors, and the adresses pointed to by buffers[i].begin() and buffers[i].end(). With “main buffer” I mean the values I get when I call buffers.begin() and buffers.end().
Main Buffer begin: 0000000002068050
Main Buffer end : 0000000002068130
buffers[0] : 0 elements, 0000000002068160 - 0000000002068160
buffers[1] : 0 elements, 0000000002070080 - 0000000002070080
buffers[2] : 0 elements, 0000000002068E70 - 0000000002068E70
buffers[3] : 0 elements, 0000000001F71810 - 0000000001F71810
buffers[4] : 0 elements, 0000000002068BB0 - 0000000002068BB0
buffers[5] : 0 elements, 00000000020688F0 - 00000000020688F0
buffers[6] : 0 elements, 0000000002068370 - 0000000002068370
Now my question is, how could I have corrupted _Mylast? (I’ve corrupted the heap, somehow, anyway)
This problem only started popping up when I moved an algorithm which was previously just a function defined at global scope into a class. I suspect it has to do with how C++ handles vectors as class members.
My builder class should be able to set up an amount of buffers (the vector stuff) and pop and push Nodes into these buffers for as long as it’s alive. That’s what I’m trying to achieve.
You write to
buffers[d-1]even whendis zero. Could that be your issue? Out-of-bounds errors sometimes aren’t detected until later on (such as when the vector gets deallocated).