假设我有这个简单的程序:
int main()
{
int myInt = 12;
int* intPtr = &myInt;//alias
std::cout << *intPtr << "\n";
delete intPtr; //This statement makes the program crash, why?
return 0;
}
我的问题是上述计划中的评论。
我对可能导致崩溃的原因的猜测是,当myInt
超出范围时,程序完成后,它将从堆栈中删除,但内存已被删除,但我我不确定。
答案 0 :(得分:3)
基本上是因为运行时使用一些数据结构来存储有关已动态分配的所有内存块的信息。当您在指针上调用delete
时,运行时会在数据结构中查找指针并标记以某种方式释放的相应内存块。运行时通常不会检查您传入的指针是否真的分配了new
:这是您作为程序员确保的责任。如果你违反了delete
的前提条件,那么内存管理算法会做一些不可预测的事情,当一些涉及内存的不可预测的事情发生时,结果往往会崩溃。
这是未定义行为的一个很好的例子。运行时可以检查指针是否已分配new
,但这会降低程序的速度。允许某些事物是未定义的行为使得生成更有效的代码成为可能。
答案 1 :(得分:1)
对delete
返回的指针以外的任何内容使用new
是未定义的行为。
对delete[]
返回的指针以外的任何内容使用new[]
是UB。
对free
返回的指针以外的任何内容使用malloc
为UB。
Valgrind和其他内存消毒剂通常可以检测到这类问题,但如果你的程序设计良好(使用更多智能指针!),那么它往往不会发生。