[问题] delete p和delete[] p 区别

目录

区别

延伸


区别

简单来说:delete p会调用一次析构函数,而delete[] p会调用每个成员的析构函数。

class A {
public:
	~A() { cout << "A的析构函数" << endl; }
};
int main() 
{
	A* pA = new A[10];
	delete[]pA;//输出10次A的析构函数
	//delete pA;//会出错,因为只析构了一次

	A* pA1 = new A;
	delete pA1;//输出一次A的析构函数
	//delete[] pA1;//编译器不会报错,但是系统会一直调用析构函数

	int* pInt = new int[10];
	delete[] pInt;
	//delete pInt;//不会出错
	int* pInt1 = new int;
	delete pInt1;
	//delete[] pInt1;//不会出错
	
	return 0;
}

由上面的代码可以看出,delete[] p和delete p的区别在于他们对于非内部数据对象处理上

如果数组类型是自定义类,那么new[]只能用delete[]来对应,new和delete对应;

但是对于普通数据类型而言,他们作用的效果是一样的,例如int* p=new int[10],delete p和delete[] p作用效果是一样的,原因是内部普通数据类型没有析构函数

这边针对“普通数据类型delete和delete[]效果一样”再做另一个例子说明:

int *p = new int[10];
int a = 102;
int *q = &a;
std::list<int *> m_listInt;
for (int i = 0; i< 10; i++)
{
    *(p+i) = i + 100;
    m_listInt.push_back(p+i);
}

//正常释放
for (auto it = m_listInt.begin(); it != m_listInt.end(); )
{
    it = m_listInt.erase(it);
}
m_listInt.clear();

delete[] p;

//代码段二
for (auto it = m_listInt.begin(); it != m_listInt.end(); )
{
    int *qq;
    qq = *it;
    it = m_listInt.erase(it);
    delete qq;        //本意是想逐个元素提取出来后删除,但是执行完此句后,内存都全部释放了
}
m_listInt.clear();

原先我是想用代码段二,将元素逐个从list内提取移除后,释放数据本身内存,但是执行了delete qq后,list队列内的其他数据内存也被释放了。这就是对于普通数据而言,delete和delete[]实现的效果是一样的。

所以会有这样一个题目:

char *p = new char[100];

delete p;

这样会有什么问题?

实际上正确的回答是:不会有内存泄漏,但是不建议这样使用。

延伸

这边简单说一下new、delete和malloc、free的区别

①malloc/free是c中的库函数,用来动态申请/释放内存空间;

②new/delete是c++中的关键字,需要编译器支持,允许重载,new会调用构造函数、delete会调用析构函数;

③new 不用指定内存块大小,会根据类型信息自己申请,malloc则需要显式指出所需内存的大小;

④new返回类型为指针,类型严格与对象匹配,而malloc成功返回void*,需要强制类型转换为我们需要的类型;

⑤new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL;

⑥new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从上动态分配内存。

注意:

此处我个人认为,自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区,可以位于堆之上也可以通过重载位于全局存储区(偏逻辑概念)。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配(偏物理概念)。

如有不对,请指正。


相关参考链接:参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值