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中进行内存管理,这free(pointer)将释放所有指向的空间pointer.现在,当我尝试用C++做一些简单的事情时,我会感到困惑.
如果我有一个二维数组的双精度分配方式与此类似
double** atoms = new double*[1000];
for(int i = 0; i < 1000; i++)
atoms[i] = new double[4];
Run Code Online (Sandbox Code Playgroud)
什么是释放新分配的堆上的内存的正确方法?
我的想法原来是这样的(因为我的大脑在用C思考):
for(int i = 0; i < 1000; i++)
delete atoms[i];
delete atoms;
Run Code Online (Sandbox Code Playgroud)
但是我忘记了delete[]运算符的存在,所以我相信正确的方法如下:
for(int i = 0; i < 1000; i++)
delete[] atoms[i];
delete[] atoms;
Run Code Online (Sandbox Code Playgroud)
理解delete和delete[]运营商之间的区别是否重要?或者我可以假设每当我分配一个数组时,ptr = new x[]我还必须解除分配delete[] ptr?
因此,在代码审查期间,我的一位同事使用了a double* d = new double[foo];然后调用了delete d.我告诉他们应该改变它delete [] d.他们表示编译器不需要基本数据类型.我不同意.
所以我想我会通过实验证明我的观点:
#define NUM_VALUES 10000
int main(int argc,char** argv)
{
int i = 0;
while (true)
{
std::cout << i << "|";
double* d = new double[NUM_VALUES];
std::cout << ((void*)d) << std::endl;
for (int j = 0; j < NUM_VALUES; j++)
d[j] = j;
delete d;
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不仅内存使用量不增长,而且每次都将d分配到同一个地方!(Visual Studio 2010).这是visual studio编译器的怪癖吗?或者这是标准的一部分?
如果你说过
int *arr = new int[5];
Run Code Online (Sandbox Code Playgroud)
有什么区别
delete arr;
Run Code Online (Sandbox Code Playgroud)
和
delete [] arr;
Run Code Online (Sandbox Code Playgroud)
我问这个是因为我试图释放二维数组的内存并且
delete [][] arr;
Run Code Online (Sandbox Code Playgroud)
似乎不起作用,但是
delete arr;
Run Code Online (Sandbox Code Playgroud)
似乎工作正常
先感谢您!
假设我只想分配256字节的内存块
char * memory = new char[256];
Run Code Online (Sandbox Code Playgroud)
比我使用placement new来创建一个FooBar对象(sizeof(Foobar)<= 256)
FooBar * obj = new (memory) FooBar();
Run Code Online (Sandbox Code Playgroud)
不
delete obj; //this also calls the destructor of FooBar
Run Code Online (Sandbox Code Playgroud)
删除所有256字节的内存?
标准是否保证仅通过"删除obj"来释放整个"内存"缓冲区?或者它基于类型"FooBar",因此此操作具有未定义的行为?
假设:FooBar是内存缓冲区中唯一的对象.
这不是重复的问题,请先了解问题.这个代码的作用并不是很明显.
将C++中的每个指针删除为指向数组的指针是否安全?
如果我总是delete [] ptr在不考虑ptr实际情况的情况下编写它是否会对我好- 无论是指向单个对象还是对象数组的指针?
我有下面的代码崩溃.
aClass *ptr_obj = new aClass[5];
delete ptr_obj;
Run Code Online (Sandbox Code Playgroud)
我知道,ptr_obj将使用delete []删除,但我的问题是,当我使用delete时它崩溃的原因.我以为它会将析构函数称为第一个对象而不是崩溃.请帮忙.
这行代码是否有效:
boost::shared_array<struct sockaddr> addr(
reinterpret_cast<struct sockaddr *>(
(ipv6 ? new unsigned char [sizeof(struct sockaddr_in6)]
: new unsigned char [sizeof(struct sockaddr_in)])
)
);
Run Code Online (Sandbox Code Playgroud)
请注意分配和类型中给出的类型之间的两种不同数据类型<template>.
这行代码是否有效:
boost::shared_ptr<struct sockaddr> addr(
reinterpret_cast<struct sockaddr *>(
(ipv6 ? new unsigned char [sizeof(struct sockaddr_in6)]
: new unsigned char [sizeof(struct sockaddr_in)])
)
);
Run Code Online (Sandbox Code Playgroud)
请注意分配和类型中给出的类型之间的两种不同数据类型<template>.
boost::shared_array<unsigned char> address(new unsigned char [sizeof(sockaddr_in)]);
Run Code Online (Sandbox Code Playgroud)
注意:使用相同类型的unsigned char,其大小恰好是所需的大小.
然后当我打算使用它时:
bind(, (sockaddr*)address.get(), );
Run Code Online (Sandbox Code Playgroud) 据我所知,
int * createArray ( void )
{
int * arr = (int*)malloc(3*sizeof(int));
arr[0] = 69; arr[1] = 69; arr[2];
return arr;
}
int main ()
{
int * myArray = createArray();
free myArray;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将释放数组的所有内存{69, 69, 69}在指向的内存地址myArray,但是
void freeArray ( int * A )
{
free A;
}
int main ()
{
int * myArray = (int*)malloc(3*sizeof(int));
myArray[0] = 69; arr[1] = 69; arr[2] = 69;
freeArray(myArray);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不会做同样的事情.这让我感到困惑的原因是因为在这两种情况下你都在处理原始指针的副本,但是从该副本中删除指向的对象仅适用于第一种情况.这似乎是一种不一致,但也许我完全错了.有人可以为我清除这个吗?
c++ ×9
arrays ×3
allocation ×1
c ×1
malloc ×1
new-operator ×1
pod ×1
pointers ×1
shared-ptr ×1