如何清除堆上分配的未使用数组的整个内存

Posted

技术标签:

【中文标题】如何清除堆上分配的未使用数组的整个内存【英文标题】:How to cleared off the whole memory for the unused array allocated on the heap 【发布时间】:2014-11-15 21:15:15 【问题描述】:

我对 delete[] p 有一些疑问。我写了一些代码 sn-p 来测试这个功能。但我发现执行 delete[] p 后,只有前 2 个数组元素被释放,其余的没有。请看我的测试 sn-p 和输出结果如下。谁能告诉我为什么以及如何清除未使用数组的整个内存?谢谢!

#include <iostream>
using namespace std;
int main()

   int *p;
   p = new int[20];
   for(int i=0;i<20;i++)
   
       p[i]=i+1;
   
    cout<<"------------------------Before delete-------------------------"<<endl;
    for(int i=0;i<20;i++)
   
       cout<<"p+"<<i<<":"<<p+i<<endl;
       cout<<"p["<<i<<"]:"<<p[i]<<endl;
   

    delete[] p;
        cout<<"-------------------After delete------------------------"<<endl;
    for(int i=0;i<20;i++)
   
       cout<<"p+"<<i<<":"<<p+i<<endl;
       cout<<"p["<<i<<"]:"<<p[i]<<endl;
   
   return 0; 

在 www.compileronline.com 中的输出

Compiling the source code....
$g++ main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1


Executing the program....
$demo

------------------------Before delete-------------------------
p+0:0xa90010
p[0]:1
p+1:0xa90014
p[1]:2
p+2:0xa90018
p[2]:3
p+3:0xa9001c
p[3]:4
p+4:0xa90020
p[4]:5
p+5:0xa90024
p[5]:6
p+6:0xa90028
p[6]:7
p+7:0xa9002c
p[7]:8
p+8:0xa90030
p[8]:9
p+9:0xa90034
p[9]:10
p+10:0xa90038
p[10]:11
p+11:0xa9003c
p[11]:12
p+12:0xa90040
p[12]:13
p+13:0xa90044
p[13]:14
p+14:0xa90048
p[14]:15
p+15:0xa9004c
p[15]:16
p+16:0xa90050
p[16]:17
p+17:0xa90054
p[17]:18
p+18:0xa90058
p[18]:19
p+19:0xa9005c
p[19]:20
-------------------After delete------------------------
p+0:0xa90010
p[0]:0
p+1:0xa90014
p[1]:0
p+2:0xa90018
p[2]:3
p+3:0xa9001c
p[3]:4
p+4:0xa90020
p[4]:5
p+5:0xa90024
p[5]:6
p+6:0xa90028
p[6]:7
p+7:0xa9002c
p[7]:8
p+8:0xa90030
p[8]:9
p+9:0xa90034
p[9]:10
p+10:0xa90038
p[10]:11
p+11:0xa9003c
p[11]:12
p+12:0xa90040
p[12]:13
p+13:0xa90044
p[13]:14
p+14:0xa90048
p[14]:15
p+15:0xa9004c
p[15]:16
p+16:0xa90050
p[16]:17
p+17:0xa90054
p[17]:18
p+18:0xa90058
p[18]:19
p+19:0xa9005c
p[19]:20

【问题讨论】:

为 C++11 查找 unique_ptr,为旧 C++ 版本查找 auto_ptr。此外,std::shared_ptr. 我认为这段代码可能会导致分段错误,因为在删除 [] 之后读取数组时,您正在访问进程未分配的内存。 【参考方案1】:

内存被清除 - 编译器实际上不需要将其析构函数中的 int 清零。你看到的是编译器认为没有必要,所以它仍然存在。析构函数调用,内存被释放。

如果您执行以下操作,您可以更清楚地看到这一点:

struct A 
    int i;
    A() : i(7)  

    ~A() 
        std::cout << "deleting A." << std::endl;
        i = 0;
    
;

然后用A* p = new A[20]; 重复你的实验。

【讨论】:

【参考方案2】:

区分清除内存和删除内存很重要。

当内存被清除时,它被初始化为某个值——也许全为零。但是当内存被删除或释放时,它会返回到堆中。当内存被释放时,内存管理器没有义务清除内存。您看到被更改的两个字节可能来自内存管理器用来帮助跟踪缓冲区溢出的调试标记。

如果您想清除所有内存,则需要在删除它之前执行此操作 - 只有此时您仍然拥有该内存的所有权。删除后清除它是在你不拥有的内存上操作。

【讨论】:

以上是关于如何清除堆上分配的未使用数组的整个内存的主要内容,如果未能解决你的问题,请参考以下文章

模型执行后清除 TensorFlow GPU 内存

安全清除内存并重新分配

我将如何清除整个阵列?

在堆上分配内存还是传递工作内存? [关闭]

在C中的堆上分配数组

清除 R 会话分配的内存(gc()没有帮助!)[重复]