为什么 delete[] 会导致堆损坏错误?
Why does delete[] result in heap corruption error?
我帮朋友调试了一段代码,有问题的部分是这样的:
class MyClass {
char * text;
public:
MyClass(const char * c) {
if (c != nullptr) {
text = new char[strlen(c)];
strcpy(text, c);
}
else
text = nullptr;
}
~MyClass() {
delete[] text;
}
};
int main() {
MyClass foo("bar");
return 0;
}
当然问题出在strlen(c)
,应该是strlen(c) + 1
。无论如何,让我感到惊讶的是,为什么在析构函数中调用 delete[] 时会导致堆损坏错误?是什么原因造成的?
调试器抛出这个错误,我的问题是:
为什么这个错误在释放内存的时候弹出,而不是更早?
以这种方式查找代码中的任何错误会容易得多。
@edit old c = nullptr -> text = nullptr
我不小心写了这个错误,(抱歉,我没有注意到,现在是我的意思)。问题是,在此任务中禁止使用字符串,因此必须以 C 方式完成。
抱歉进行了这么多编辑。我真的必须学会如何提出精确的问题。
堆损坏是由对 strcpy
的调用引起的,它写入了已分配内存块的末尾。当代码调用 delete[]
.
时,它被 检测到
为什么这个错误是在释放内存的时候弹出的,而不是更早的?
根据经验,当发生损坏时,Visual Studio 中不一定会检测到堆损坏。您不能依赖在损坏之后发生的检测。尽管在这种情况下,在下一个可能的时间检测到损坏以检测损坏。 Visual Studio 仅在您分配或释放内存时进行检查。
我帮朋友调试了一段代码,有问题的部分是这样的:
class MyClass {
char * text;
public:
MyClass(const char * c) {
if (c != nullptr) {
text = new char[strlen(c)];
strcpy(text, c);
}
else
text = nullptr;
}
~MyClass() {
delete[] text;
}
};
int main() {
MyClass foo("bar");
return 0;
}
当然问题出在strlen(c)
,应该是strlen(c) + 1
。无论如何,让我感到惊讶的是,为什么在析构函数中调用 delete[] 时会导致堆损坏错误?是什么原因造成的?
调试器抛出这个错误,我的问题是: 为什么这个错误在释放内存的时候弹出,而不是更早? 以这种方式查找代码中的任何错误会容易得多。
@edit old c = nullptr -> text = nullptr 我不小心写了这个错误,(抱歉,我没有注意到,现在是我的意思)。问题是,在此任务中禁止使用字符串,因此必须以 C 方式完成。 抱歉进行了这么多编辑。我真的必须学会如何提出精确的问题。
堆损坏是由对 strcpy
的调用引起的,它写入了已分配内存块的末尾。当代码调用 delete[]
.
为什么这个错误是在释放内存的时候弹出的,而不是更早的?
根据经验,当发生损坏时,Visual Studio 中不一定会检测到堆损坏。您不能依赖在损坏之后发生的检测。尽管在这种情况下,在下一个可能的时间检测到损坏以检测损坏。 Visual Studio 仅在您分配或释放内存时进行检查。