简体   繁体   English

C ++中的内存管理。

[英]Memory management in C++.

I have the following program: 我有以下程序:

//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;
  }
}

When I put the following into gdb and insert a break point at float *arr ... , I step through the program and observe the following: 当我将以下内容放入gdb并在float *arr ...插入一个断点时,我逐步执行该程序并观察以下内容:

  1. Printing the array arr after it has been initialized gives me 1 17 times. arr初始化后打印阵列给我1 17次。
  2. Inside someFunc too, I print arr before delete to get the same print as above. someFunc里面,我在delete之前打印arr以获得与上面相同的打印。
  3. Upon going back into main , when I print arr , I get the first digit as 0 followed by 16 1.0s. 回到main ,当我打印arr ,我得到第一个数字为0,然后是16个1.0s。

My questions: 我的问题:
1. Once the array has been deleted in someFunc , how am I still able to access arr without a segfault in someFunc or main ? 1.在someFunc删除数组someFunc ,如何在someFuncmain没有段错误的情况下仍能访问arr
2. The code snippet above is a test version of another piece of code that runs in a bigger program. 2.上面的代码片段是在更大的程序中运行的另一段代码的测试版本。 I observe the same behaviour in both places (first digit is 0 but all others are the same. If this is some unexplained memory error, how am I observing the same thing in different areas? 我在两个地方观察到相同的行为(第一个数字是0但是所有其他数字都是相同的。如果这是一些无法解释的记忆错误,我如何在不同的区域观察同样的事情?
3. Some explanations to fill the gaps in my understanding are most welcome. 我们非常欢迎一些解释来填补我理解中的空白。

A segfault occurs when you access a memory address that isn't mapped into the process. 当您访问未映射到进程的内存地址时,会发生段错误。 Calling delete [] releases memory back to the memory allocator, but usually not to the OS. 调用delete []会将内存释放回内存分配器,但通常不会释放到操作系统。

The contents of the memory after calling delete [] are an implementation detail that varies across compilers, libraries, OSes and especially debug-vs-release builds. 调用delete []之后内存的内容是一个实现细节,它在编译器,库,操作系统以及特别是调试版与发行版之间有所不同。 Debug memory allocators, for instance, will often fill the memory with some tell-tale signature like 0xdeadbeef. 例如,调试内存分配器通常会为内存填充一些像0xdeadbeef这样的告密签名。

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

Once the array has been deleted, any access to it is undefined behavior. 删除数组后,对它的任何访问都是未定义的行为。 There's no guarantee that you'll get a segment violation; 我们无法保证您会收到违规行为; in fact, typically you won't. 事实上,通常你不会。 But there's no guarantee of what you will get; 但是不能保证你会得到什么; in larger programs, modifying the contents of the array could easily result in memory corruption elsewhere. 在较大的程序中,修改数组的内容很容易导致其他地方的内存损坏。

delete gives the memory back to the OS memory manager, but does not necessarily clears the contents in the memory(it should not, as it causes overhead for nothing). delete将内存返回给OS内存管理器,但不一定清除内存中的内容(它不应该,因为它会导致无任何开销)。 So the values are retained in the memory. 因此值保留在内存中。 And in your case, you are accessing the same memory -- so it will print what is in the memory -- it is not necessarily an undefined behaviour(depends on memory manager) 在你的情况下,你正在访问相同的内存 - 所以它将打印内存中的内容 - 它不一定是未定义的行为(取决于内存管理器)

Re 1: You can't. 回复1:你做不到。 If you want to access arr later, don't delete it. 如果您想稍后访问arr,请不要删除它。

C++ doesn't check for array boundaries. C ++不检查数组边界。 Only if you access a memory which you are not allowed to you will get segfault 只有当您访问不允许的内存时,才会出现段错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM