2011-08-09 80 views
2

我有以下程序:C++中的内存管理。

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

我的问题:
1.一旦阵列已someFunc被删除了,我怎么还能够访问arr没有someFuncmain段错误?
2.上面的代码片段是在更大的程序中运行的另一段代码的测试版本。我在两个地方观察到相同的行为(第一个数字是0,但所有其他数字都是相同的。如果这是一些无法解释的内存错误,我如何在不同区域观察相同的东西?
3.有些解释填补了空白我的理解是最欢迎的。

回答

3

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

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

+0

或至少不立即 - 有缓存取决于系统的记忆本质,其行为有所不同。 –

1

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

3

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

2

一旦数组被删除,对它的任何访问都是未定义的行为。 无法保证您会收到细分受众群违规问题;实际上, 通常你不会。但是不能保证你会得到什么;在 较大的程序中,修改数组的内容很容易导致 在其他地方的内存损坏。

0

C++不检查数组边界。只有当你访问你不准你会得到段错误

2

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

+0

这是未定义的行为。它在标准中被规定。 – ninjalj