c++中的内存管理

Memory management in C++.

本文关键字:管理 内存 c++      更新时间:2023-10-16

我有以下程序:

//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中,我在delete之前打印arr以获得与上面相同的打印。
  3. 回到main,当我打印arr时,我得到的第一个数字是0,后面跟着16个1.0。

我的问题:1. 一旦在someFunc中删除了数组,我如何仍然能够在someFuncmain中访问arr而没有段故障?
2. 上面的代码片段是在一个更大的程序中运行的另一段代码的测试版本。我在两个地方观察到相同的行为(第一个数字是0,但所有其他都是相同的。如果这是某种无法解释的记忆错误,我如何在不同的区域观察到同样的事情?
3.

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

调用delete []后的内存内容是一个实现细节,在不同的编译器、库、操作系统,特别是调试与发布版本之间是不同的。例如,调试内存分配器通常会用一些泄露信息的签名(如0xdeadbeef)填充内存。

在指针被delete编辑后对其解引用是未定义的行为,这意味着任何事情都可能发生

一旦数组被删除,任何对它的访问都是未定义的行为。这并不能保证你会得到分段违例;事实上,通常你不会。但这并不能保证你会得到什么;在在较大的程序中,很容易修改数组的内容在其他地方的内存损坏。

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

Re 1:你不能。如果以后要访问arr,请不要删除它

c++不检查数组边界。只有当你访问一个你不允许访问的内存时,你才会得到段错误