从堆中删除数组

Sae*_*omi 11 c++ arrays valgrind memory-leaks

我的问题是从堆内存中删除一个数组.我读过一本书,这个博客和其他资源,像这样的,他们都表示,从堆删除阵列,我们必须使用[]在后delete ,所以如果我们写代码,而无需使用功能,[]那么我们已经泄漏的内存.

例如,考虑下面的程序

int *s = new int[10];
delete [] s;
Run Code Online (Sandbox Code Playgroud)

我通过使用valgrind软件包在Linux中测试了这个小程序(这个程序包可以检查错误编码产生的泄漏内存量).通过Linux下面的命令,我们看到一切都没问题

sudo valgrind --leak-check=full ./<path_to_exe_file>
Run Code Online (Sandbox Code Playgroud)

这是Linux命令的输出

 ==4565== HEAP SUMMARY:
 ==4565==     in use at exit: 0 bytes in 0 blocks
 ==4565==   total heap usage: 1 allocs, 1 frees, 40 bytes allocated
 ==4565== 
 ==4565== All heap blocks were freed -- no leaks are possible
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用delete不使用[]时出现了我的问题,当我检查输出时,valgrind我看到所有堆内存都被释放,所以它是否正确?或者valgrind不知道整个堆没有被释放,阵列的某些部分仍然在那里!! ?? 如果valgrind无法检测到这种泄漏的内存,那么有任何可以检测到的包.

Mar*_*rst 5

调用delete数组而不使用[]未定义行为的结果.未定义的行为可能是正确删除了数组,这似乎是您观察到的.但是,你不能依赖于此.

  • 不,没有泄露的记忆 - 你很幸运. (2认同)

cma*_*ter 5

马丁·布罗德赫斯特已经给出了正确的律师语言答案。我将给出技术细节答案:

delete[]使用over的要点delete是,运算符无法知道delete传递的指针是指向数组还是指向单个对象。因此,delete仅删除单个对象,同时delete[]调用一些额外的魔法来恢复数组的大小,然后继续删除所有元素。

现在删除由两个不同的部分组成:

  1. 必须通过调用析构函数来销毁对象。对于数组,这意味着对每个数组元素调用一次析构函数。

  2. 已使用的内存必须标记为空闲,以便可以重复使用。这是 C++ 中全局的工作operator delete()。由于数组是连续存储的,因此这是对整个数组的一次调用。

valgrind只关心内存。因此,它挂钩诸如malloc()free()operator new()和 之类的内存分配函数operator delete()

delete当您调用而不是调用时,会发生delete[]第一个对象被破坏,并且指针被传递到operator delete(). operator delete()不知道存储在内存区域内的对象,无论如何它们已经被销毁,因此它将成功地将内存区域标记为空闲。valgrind看到这个operator delete()调用,并且很高兴,因为所有内存都可以免费重用。但是,您的代码未能正确破坏除第一个数组元素之外的所有元素。这很糟糕。