Sat*_*bir 44 c++ memory-management pod
IP_ADAPTER_INFO *ptr=new IP_ADAPTER_INFO[100];
Run Code Online (Sandbox Code Playgroud)
如果我免费使用
delete ptr;
Run Code Online (Sandbox Code Playgroud)
它会导致内存泄漏,如果不是那么为什么?
这是VS2005生成的反汇编代码
; delete ptr;
0041351D mov eax,dword ptr [ptr]
00413520 mov dword ptr [ebp-0ECh],eax
00413526 mov ecx,dword ptr [ebp-0ECh]
0041352C push ecx
0041352D call operator delete (4111DBh)
00413532 add esp,4
; delete []ptr;
00413535 mov eax,dword ptr [ptr]
00413538 mov dword ptr [ebp-0E0h],eax
0041353E mov ecx,dword ptr [ebp-0E0h]
00413544 push ecx
00413545 call operator delete[] (4111E5h)
0041354A add esp,4
Run Code Online (Sandbox Code Playgroud)
sbi*_*sbi 149
这是否会导致内存泄漏,擦拭你的硬盘,让你怀孕,让讨厌的鼻腔恶魔在你的公寓周围追你,或者让一切正常,没有明显的问题,是不确定的.它可能是这种方式与一个编译器,并改变另一个,改变与新的编译器版本,每个新的编译,月相,你的心情,或取决于在最后一个阳光下通过处理器的中微子的数量下午.或者它可能不会.
所有这一切,以及无数其他可能性都被置于一个术语中:未定义的行为:
只是远离它.
jic*_*chi 14
只是对某些操作系统和编译器上某些"未定义"行为的说明.希望它可以帮助人们调试他们的代码.
测试1
#include <iostream>
using namespace std;
int main()
{
int *p = new int[5];
cout << "pass" << endl;
delete p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
测试2
#include <iostream>
using namespace std;
int main()
{
int *p = new int;
cout << "pass" << endl;
delete[] p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
测试3
#include <iostream>
using namespace std;
struct C {
C() { cout << "construct" << endl; }
~C() { cout << "destroy" << endl; }
};
int main()
{
C *p = new C[5];
cout << "pass" << endl;
delete p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
测试4
#include <iostream>
using namespace std;
struct C {
C() { cout << "construct" << endl; }
~C() { cout << "destroy" << endl; }
};
int main()
{
C *p = new C;
cout << "pass" << endl;
delete[] p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
测试1
pass
Run Code Online (Sandbox Code Playgroud)
测试2
pass
Run Code Online (Sandbox Code Playgroud)
测试3
construct
construct
construct
construct
construct
pass
destroy
# Then, pop up crash msg
Run Code Online (Sandbox Code Playgroud)
测试4
construct
pass
destroy
destroy
destroy
destroy
destroy
destroy
destroy
... # It never stop until CTRL+C
Run Code Online (Sandbox Code Playgroud)
测试1
pass
Run Code Online (Sandbox Code Playgroud)
测试2
pass
Run Code Online (Sandbox Code Playgroud)
测试3
construct
construct
construct
construct
construct
pass
destroy
a.out(71111) malloc: *** error for object 0x7f99c94000e8: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
zsh: abort ./a.out
Run Code Online (Sandbox Code Playgroud)
测试4
construct
pass
a.out(71035) malloc: *** error for object 0x7f83c14000d8: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
zsh: abort ./a.out
Run Code Online (Sandbox Code Playgroud)
测试1
pass
Run Code Online (Sandbox Code Playgroud)
测试2
pass
Run Code Online (Sandbox Code Playgroud)
测试3
construct
construct
construct
construct
construct
*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x0000000001f10018 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7fe81d878b96]
./a.out[0x400a5b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fe81d81b76d]
./a.out[0x4008d9]
======= Memory map: ========
....
zsh: abort (core dumped) ./a.out
Run Code Online (Sandbox Code Playgroud)
测试4
construct
destroy
destroy
destroy
destroy
destroy
destroy
destroy
destroy
...
destroy
destroy
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00000000016f6008 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7fa9001fab96]
./a.out[0x400a18]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fa90019d76d]
./a.out[0x4008d9]
======= Memory map: ========
...
zsh: abort (core dumped) ./a.out
Run Code Online (Sandbox Code Playgroud)
它通常不会泄漏,因为在POD析构函数很简单的情况下,不需要调用它们,所以delete
只需释放数组所占用的内存.内存释放只需要一个指针值,因此它将返回到堆中.该数组接受一个连续的内存块,因此释放可以是成功的,就像它是一个单元素的释放一样.
但不要依赖于此,因为它是未定义的行为.也许它工作正常,也许发生了可怕的事情,在这个编译器上工作,不适用于另一个,很多人都感谢你种错误.
有关详情,请参阅此答案.
在具有 new T[n] 的分配上使用 delete 运算符是未定义的,并且会因编译器而异。AFAIK,例如 MSVC 编译器将生成与 GCC 不同的代码。
如果 A 指向一个通过 new T[n] 分配的数组,那么你必须通过 delete[] A 删除它。 delete 和 delete[] 之间的区别很简单——前者销毁一个标量对象,后者销毁一个数组.
小智 5
delete:仅针对所指向的元素(如果需要)调用适当的析构函数,然后释放内存块
delete []:为数组中的每个元素调用适当的析构函数(如果需要),然后释放内存块
归档时间: |
|
查看次数: |
10743 次 |
最近记录: |