C ++中的delete
和运算符有什么区别?delete[]
6 回答
运算符释放内存并为使用创建的delete
单个对象调用析构函数new
。
运算符为使用创建的delete []
对象数组释放内存并调用析构函数new []
。
使用delete
返回的指针new []
或返回delete []
的指针new
会导致未定义的行为。
delete[]
运算符用于删除数组。delete
运算符用于删除非数组对象。在(最终)调用数组元素或非数组对象的析构函数后,它分别调用operator delete[]
和operator delete
函数来删除数组或非数组对象占用的内存。
以下显示了关系:
typedef int array_type[1];
// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;
// create and destroy an int
int *b = new int;
delete b;
// create and destroy an int[1]
int *c = new int[1];
delete[] c;
// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;
对于new
创建数组的 (因此,要么 要么new type[]
应用于new
数组类型构造),标准operator new[]
在数组的元素类型类或全局范围内查找 ,并传递请求的内存量。它可能会请求比N * sizeof(ElementType)
它想要的更多(例如存储元素的数量,因此它稍后在删除时知道要完成多少次析构函数调用)。如果该类声明一个operator new[]
额外的内存量接受另一个size_t
,则第二个参数将接收分配的元素数量 - 它可以将其用于它想要的任何目的(调试等......)。
对于new
创建非数组对象的 ,它将operator new
在元素的类或全局范围内查找 。它传递请求的内存量(sizeof(T)
总是如此)。
对于delete[]
,它查看数组的元素类类型并调用它们的析构函数。使用的operator delete[]
函数是元素类型的类中的一个,或者如果没有,则在全局范围内。
对于delete
,如果传递的指针是实际对象类型的基类,则基类必须具有虚拟析构函数(否则,行为未定义)。如果它不是基类,则调用该类的析构函数,并使用operator delete
该类中的 an 或全局operator delete
。如果传递了基类,则调用实际对象类型的析构函数,并使用operator delete
在该类中找到的析构函数,或者如果没有,operator delete
则调用全局。如果operator delete
类中的第二个参数类型为size_t
,它将接收要释放的元素数。
malloc
这是 c++ / free
, new
/ delete
, new[]
/中 allocate/DE-allocate 模式的基本用法
delete[]
我们需要相应地使用它们。但我想为delete
和之间的区别添加这种特殊的理解delete[]
1)delete
用于解除分配给单个对象的内存
2)delete[]
用于取消分配为对象数组分配的内存
class ABC{}
ABC *ptr = new ABC[100]
当我们说时new ABC[100]
,编译器可以获得关于需要分配多少个对象的信息(这里是 100),并为每个创建的对象调用构造函数
但相应地,如果我们简单地delete ptr
用于这种情况,编译器将不知道有多少对象ptr
指向并且最终会调用析构函数并删除仅 1 个对象的内存(留下析构函数的调用和剩余 99 个对象的释放)。因此会有内存泄漏。
所以我们需要delete [] ptr
在这种情况下使用。
运算符delete
和delete []
分别用于销毁使用new
和创建的对象new[]
,返回分配给编译器内存管理器可用的内存。
用 来创建的对象new
必须用 来销毁,用来delete
创建的数组new[]
应该用 来删除delete[]
。
当我问这个问题时,我真正的问题是,“两者之间有区别吗?运行时不是必须保留有关数组大小的信息,所以它无法分辨我们指的是哪一个吗?” 这个问题没有出现在“相关问题”中,所以只是为了帮助像我这样的人,这里是答案:“为什么我们甚至需要 delete[] 运算符?”
delete
用于单个指针,delete[]
用于通过指针删除数组。
这可能会帮助您更好地理解。