我有以下程序:
//simple array memory test.
#include <iostream>
using namespace std;
void someFunc(float*, int, int);
int main() {
int convert = 2;
float *arr = new float[17];
for(int i = 0; i < 17; i++) {
arr[i] = 1.0;
}
someFunc(arr, 17, convert);
for(int i = 0; i < 17; i++) {
cout << arr[i] << endl;
}
return 0;
}
void someFunc(float *arr, int num, int flag) {
if(flag) {
delete []arr;
}
}
当我将以下内容放入gdb
并在float *arr ...
插入一个断点时,我会逐步完成该程序并观察以下内容:
arr
后打印给我1 17次。 someFunc
内,我在arr
之前打印delete
以获得与上面相同的印刷品。main
后,当我打印arr
时,我得到第一个数字为0,然后是16个1.0。 我的问题:
1.在someFunc
中删除数组后,如何在arr
或someFunc
中没有段错误的情况下仍能访问main
?
2.上面的代码片段是在更大的程序中运行的另一段代码的测试版本。我在两个地方都观察到相同的行为(第一个数字是0
但是所有其他都是相同的。如果这是一些无法解释的记忆错误,我如何在不同的区域观察同样的事情?
我们非常欢迎一些解释来填补我理解中的空白。
答案 0 :(得分:3)
当您访问未映射到进程的内存地址时,会发生段错误。调用delete []
会将内存释放回内存分配器,但通常不会释放到操作系统。
调用delete []
后内存的内容是一个实现细节,它在编译器,库,操作系统以及特别是调试版与发行版之间有所不同。例如,调试内存分配器通常会在内存中填充一些像0xdeadbeef这样的告密签名。
答案 1 :(得分:3)
在delete
之后取消引用指针是未定义的行为,这意味着任何事情都可能发生。
答案 2 :(得分:2)
删除数组后,对它的任何访问都是未定义的行为。 我们无法保证您会收到违规行为;事实上, 通常你不会。但是不能保证你会得到什么;在 更大的程序,很容易导致修改数组的内容 在其他地方的记忆腐败
答案 3 :(得分:2)
delete
将内存返回给操作系统内存管理器,但不一定清除内存中的内容(它不应该,因为它会导致无任何开销)。因此值保留在内存中。在你的情况下,你正在访问相同的内存 - 所以它将打印内存中的内容 - 它不一定是未定义的行为(取决于内存管理器)
答案 4 :(得分:1)
回复1:你做不到。如果您想稍后访问arr,请不要删除它。
答案 5 :(得分:0)
C ++不检查数组边界。只有当您访问不允许的内存时才会出现段错误