C++中delete和delete[]运算符有什么区别?
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) 有一些情况,C++标准将其定义为未定义的行为.例如,如果我分配new[],然后尝试释放delete(不delete[])那是未定义的行为 - 任何事情都可能发生 - 它可能会起作用,它可能会崩溃,它可能会默默地破坏某些东西并设置一个定时问题.
解释这一点很有问题,新手可能会发生任何事情.他们开始"证明""这是有效的"(因为它确实适用于他们使用的C++实现),并询问"这可能是什么问题"?我能给出什么简洁的解释会激励他们不写这样的代码?
我一直在尽力学习C++,但我之前的培训在一个主要问题上不足:内存管理.我的主要语言都有自动垃圾收集,所以跟踪一切从来没有真正必要.我已经尝试过在线阅读C++中的内存管理,但我对此感到怀疑,因为我遗漏了一些东西.
所以,这是一个多部分的问题:
delete在循环重新迭代之前调用任何新指针.它是否正确?你需要用引用做些什么吗?mallocfreecallocrealloc***********************更新*******************
这是为了解释在评论一中对lmgtfy的引用(由Ewan提供).如果您开始阅读那里可用的信息,则对初学者没用.我认为这是一个伟大的理论,但它对这个问题既不相关也不有用.
在C ++中,以下代码中的指针p和q之间是否有区别?
int* p = new int;
int* q = new int[5];
Run Code Online (Sandbox Code Playgroud)
我知道一个为单个int分配新内存,第二个为5个int数组分配内存,但是从根本上说,指向单个int的指针和指向一个int数组的指针之间有什么区别吗?
我对此感到疑惑,因为我读到必须使用它delete[] q来释放q指向的内存,而只是释放delete pp指向的单个int。如果我使用会怎样delete q?
我正在使用auto_ptr<>它使用类指针类型的数组,所以我如何为它赋值.
例如
auto_ptr<class*> arr[10];
如何为arr数组赋值?
是否有区别:
operator delete(some_pointer);
Run Code Online (Sandbox Code Playgroud)
和
delete some_pointer;
Run Code Online (Sandbox Code Playgroud)
如果是这样,有什么区别,哪一个应该使用一个以及该运营商的另一个版本?谢谢.
我的问题是从堆内存中删除一个数组.我读过一本书,这个博客和其他资源,像这样的,他们都表示,从堆删除阵列,我们必须使用[]在后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无法检测到这种泄漏的内存,那么有任何可以检测到的包.
在软件会议中进行讨论之后,我已经着手查明是否删除带有plain的动态分配的primitives数组delete会导致内存泄漏.
我编写了这个小程序并使用在Windows XP上运行的visual studio 2008进行编译:
#include "stdafx.h"
#include "Windows.h"
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int i =0; i < 1024*1000; i++)
{
int* p = new int[1024*100000];
for (int j =0;j<BLOCK_SIZE;j++) p[j]= j % 2;
Sleep(1000);
delete p;
}
}
Run Code Online (Sandbox Code Playgroud)
我比使用任务管理器监视我的应用程序的内存消耗,令人惊讶的是内存被正确分配和释放,分配的内存没有像预期的那样稳定增加
我修改了我的测试程序来分配一个非原始类型的数组:
#include "stdafx.h"
#include "Windows.h"
struct aStruct
{
aStruct() : i(1), j(0) {}
int i;
char j;
} NonePrimitive;
const unsigned long BLOCK_SIZE = 1024*100000;
int _tmain()
{
for (unsigned int …Run Code Online (Sandbox Code Playgroud) 我总是被告知在使用new []分配的数组上调用delete是不安全的.你应该总是将new与delete和new []与delete []配对.
所以我很惊讶地发现以下代码在VS2008下的Debug和Release模式下编译并运行正常.
class CBlah
{
public:
CBlah() : m_i(0) {}
private:
int m_i;
};
int _tmain(int argc, _TCHAR* argv[])
{
for(;;)
{
CBlah * p = new CBlah[1000]; // with []
delete p; // no []
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我花了一段时间才弄清楚它为什么会起作用,我认为这只是运气和一些未定义的行为.
但是......它让我想知道......为什么Visual Studio没有选择这个,至少在Debug内存管理器中呢?是因为有很多代码出现了这个错误并且他们不想破坏它,或者他们觉得调试内存管理器的工作不是要抓住这种错误吗?
有什么想法吗?这种滥用是否常见?