我有一个课程,我们称之为Builder。它有一个声明为
的私有成员vector< vector< Node >> buffers; // Node is a pure data class.
在这个Builder类构造函数中,我这样做:
buffers = vector< vector< Node >>(amount);
其中“amount”仅在运行时已知。
在构建器类的生命周期中,会在buffers成员上调用几个操作。我正在使用的唯一操作是:
buffers[i].push_back(Node());
buffers[i].clear();
我只是在这里添加算法的内容以供参考:
// 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
}
}
当Builder类对象超出范围时,它会被破坏,并且它也会被它的类成员破坏。当我在VS2010调试模式时,没有问题。在发布模式下,我收到以下错误:“Windows已触发断点”。
问题在于STL:vector规范的这一部分,在_Destroy调用。
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;
}
查看调试器,我可以看到_Mylast的值不正确(0x000000000000),这可能是导致此解除分配失败的原因。当我尝试在最后执行buffers.clear()时,我得到了相同的结果。 (buffers [i] .clear()工作正常)。此外,当我点击“继续”时,我的程序也能正常工作。
我的算法在运行后有一些输出。你看到的是各个向量中的元素数量,以及buffers [i] .begin()和buffers [i] .end()指向的地址。 “主缓冲区”是指我调用buffers.begin()和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
现在我的问题是,我怎么会损坏_Mylast? (无论如何,我已经腐败了堆)
当我将以前只是在全局范围内定义的函数移动到类中时,这个问题才开始出现。我怀疑它与C ++如何处理向量作为类成员有关。
我的构建器类应该能够设置一定数量的缓冲区(向量内容),并将节点弹出并推送到这些缓冲区中,只要它还活着。这就是我想要实现的目标。
答案 0 :(得分:3)
即使buffers[d-1]
为零,您也会写信d
。这可能是你的问题吗?有时甚至直到稍后才检测到越界错误(例如当向量被解除分配时)。
答案 1 :(得分:0)
确保您的Node
个对象可以被复制并随后被正确销毁;一个非常常见的错误就是让你的包含对象(在这种情况下是Node
)在它的析构函数中做一些依赖于它的所有底层数据的唯一副本。您可能希望缓冲区存储shared_ptr<Node>
以防止复制开销,或者至少确保已实现Node::Node(const Node &)
和Node::operator=(const Node &)
以确保复制语义正确(以及将Node
内的任何原始指针也改为shared_ptr
。
您可能还想阅读RAII principles,因为这有助于防止这些错误。