我使用的是Visual Studio 2008并编译了以下代码。
代码1:
int* pI = new int[3];
delete pI;
代码2:
int* pJ = new int[3];
delete[] pJ;
显然,Code1是错误的,因为pI被分配了“operator new []”。
然后是问题:
如果我在项目中使用“Code1”,
答案 0 :(得分:2)
首先:不要这样做。只是不要。基本上永远是使用new
的数组形式的一个很好的理由(对于反对者:不,甚至在你写一个集合类时)。我在实际代码中已经使用了20多年(之前不应该使用,但当时没有意识到)。通常,您应该使用std::vector
代替。
然后简短的回答:我不知道将会诊断出这个(至少是可靠的)编译器。当/如果你这样做,就会得到未定义的行为,这基本上意味着你已经破坏了与编译器签订合同的一面,从而消除了它的所有义务。
至于在实践中可能发生的事情:这似乎随编译器而变化。在某些情况下,你的内存块将被释放而不运行它包含的对象的析构函数(在你的情况下无关紧要,因为int
的dtor基本上是一个nop)。在其他情况下,代码将崩溃并烧毁。例如,请考虑以下代码:
#include <iostream>
#include <iomanip>
struct foo {
~foo() { std::cout << "~foo()\n"; }
};
int main() {
foo *g = new foo[5];
delete g;
}
使用VS 2015或g ++ 5.3时,会崩溃并烧毁(即弹出一个对话框,告诉您程序已停止工作)。
对于一些较旧的编译器,析构函数只运行一次,而不是破坏创建的对象所需的5次。
答案 1 :(得分:1)
一些使用静态分析工具的编译器可以检测代码中的静态事件,这些事件永远无法正常运行。但是在所有情况下他们都无法检测到所有这些错误。特别是动态的案例。
它会破坏堆(什么样的腐败)?
未定义,因为未正确删除数组的行为。它可能工作得很好。它可能会破坏记忆。它可能会破坏堆。它可能会使你的程序崩溃。
这就是“未定义的行为”的含义。