C ++中的内存管理。

时间:2011-08-09 12:03:14

标签: c++ memory-management

我有以下程序:

//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 ...插入一个断点时,我会逐步完成该程序并观察以下内容:

  1. 在初始化阵列arr后打印给我1 17次。
  2. someFunc内,我在arr之前打印delete以获得与上面相同的印刷品。
  3. 回到main后,当我打印arr时,我得到第一个数字为0,然后是16个1.0。
  4. 我的问题:
    1.在someFunc中删除数组后,如何在arrsomeFunc中没有段错误的情况下仍能访问main? 2.上面的代码片段是在更大的程序中运行的另一段代码的测试版本。我在两个地方都观察到相同的行为(第一个数字是0但是所有其他都是相同的。如果这是一些无法解释的记忆错误,我如何在不同的区域观察同样的事情?
    我们非常欢迎一些解释来填补我理解中的空白。

6 个答案:

答案 0 :(得分:3)

当您访问未映射到进程的内存地址时,会发生段错误。调用delete []会将内存释放回内存分配器,但通常不会释放到操作系统。

调用delete []后内存的内容是一个实现细节,它在编译器,库,操作系统以及特别是调试版与发行版之间有所不同。例如,调试内存分配器通常会在内存中填充一些像0xdeadbeef这样的告密签名。

答案 1 :(得分:3)

delete之后取消引用指针是未定义的行为,这意味着任何事情都可能发生。

答案 2 :(得分:2)

删除数组后,对它的任何访问都是未定义的行为。 我们无法保证您会收到违规行为;事实上, 通常你不会。但是不能保证你会得到什么;在 更大的程序,很容易导致修改数组的内容 在其他地方的记忆腐败

答案 3 :(得分:2)

delete将内存返回给操作系统内存管理器,但不一定清除内存中的内容(它不应该,因为它会导致无任何开销)。因此值保留在内存中。在你的情况下,你正在访问相同的内存 - 所以它将打印内存中的内容 - 它不一定是未定义的行为(取决于内存管理器)

答案 4 :(得分:1)

回复1:你做不到。如果您想稍后访问arr,请不要删除它。

答案 5 :(得分:0)

C ++不检查数组边界。只有当您访问不允许的内存时才会出现段错误