我最近遇到了一些我用 C++ 编写的代码的问题,我无法找到解决方案。这个问题乍一看似乎很简单,但由于某种原因程序抛出错误,我无法解释原因。 我不会复制粘贴我遇到错误的原始代码(因为它太麻烦了),但这是它的简化版本,它在相同的上下文中表现出完全相同的行为:
#include<vector>
using namespace std;
class A_class
{
bool *heap_space; //can be any type of pointer
public:
A_class() { heap_space = new bool[4]; }
A_class(const A_class&) { heap_space = new bool[4]; }
~A_class() { delete[] heap_space; }
};
void main()
{
vector<A_class> ObjArr(5);
vector<A_class>::iterator iTer = ObjArr.begin() + x;
//where x can be any number from 0 to 3
ObjArr.erase(iTer);
}
我知道代码看起来简单得不切实际,但我似乎无法找出引发异常的原因。该代码将抛出“调试断言失败!”每次我尝试运行它时,都会在运行时显示“表达式:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)”消息。
提及该消息在容器的删除方法期间不会立即出现可能也很有用。它仅在 vector 超出范围后出现。 因此,我一直尝试通过各种方法修复错误,方法是在 vector 超出范围之前添加代码(例如在删除后立即重新插入新元素)但没有成功。此外,经过一些试验后,我发现该消息仅在删除 vector 的最后一个元素 (ObjArr.end()-1) 以外的任何内容后才会出现。如果 vector 的最后一个元素被删除,显然没有什么不好的事情发生。希望这些提示有所帮助。 如果有人知道为什么会发生这种情况,请向我解释。我敢肯定我只是犯了一个新手错误,因为这似乎很容易弄清楚,但我做不到。
以上代码是在 Windows 7 下使用 Visual Studio 2013 编译的。
最佳答案
有趣的是,这是因为您没有提供赋值运算符。为什么需要一个?好吧,让我们考虑一个 vector 。 vector 对象有一个指向 5 个 A_class
数组的指针。它们是默认构造的,这没有问题,因为您已经定义了它。现在我们删除:
A_class }
A_class }
A_class }-- Erase one of these
A_class }
A_class }
有趣的是,如果我们删除最后一个,我们不会发现问题,只有当我们删除索引 0 到 3 中的一个时才会出现问题。为什么?好吧,当我们删除索引 2 时,我们得到他的:
A_class
A_class
-- empty space with size = sizeof(A_class)
A_class
A_class
为了协调这个空间,在删除结束时,std::vector
使用赋值运算符来修复数组。所以 index[2] = index[3]
,index[3] = index[4]
。现在,因为您没有声明赋值运算符,它将使用默认值,包括 index[4]
的删除。这很糟糕,因为 index[4]
会给 index[3]
它的指针然后删除它,结果是这样的:
A_class // heap_space okay
A_class // heap_space okay
A_class // heap_space okay
A_class // heap_space deleted! will error when deconstructed
所以现在当我们退出时,我们试图删除 index[3]
,然后一切都崩溃了!
通过添加一个使用 swap
的赋值运算符,我们可以解决这个问题:
class A_class
{
public:
//...
// note the byval argument
A_class& operator=(A_class other) {
std::swap(this->heap_space, other.heap_space);
return *this;
}
//...
}
关于c++ - 删除对象时调试断言失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20337804/