delete和delete[]的区别

今天在看关于内存池的资料时,看到了placement new这个写法,先做一点简单介绍。

void *p = (void *)malloc(10000);
A *i = new ((A *)p) A();

cout << i << "  " << p << endl;

free(p);
p = NULL;
这个简单的例子中就使用在指定内存地址中调用构造函数,而不分配内存。这种写法在内存池中比较常见,需要注意的可能就是最后内存的回收问题和销毁对象时,析构函数的调用,在这里不做赘述。而要处理好这些问题,就需要了解一下free/malloc,new/delete的在内存中的工作方式了。

再说说主题,关于delete 和 delete[]的区别。一般的,在我们学习new这部分知识时会知道,new数组时我们使用delete[],new单个对象时,我们使用delete。那么为什么要这样呢?我是比较刨根问底的,所以我寻找了一些资料,在这里做一些总结,保留一些学习笔记,也希望帮助到他人。如果文章中有什么问题的话,还希望各位不吝指正。

那么,还是先来看例子,从例子中做总结。了解内存里比较特殊的自动可以看看这个Magic number。下面几个简单介绍截图中会出现的几个魔法数值

CDCDCDCD 该值标记未初始化过的堆内存 
DDDDDDDD 该值标记被释放了的堆内存 
FDFDFDFD 为堆分配内存前后的哨兵位.

class A
{
public:
	~A()
	{
		cout << "destructor.." << endl;
	}
};

class B
{

};

int main()
{
	
	int *p_i = new int(45);

	delete []p_i;

	A *p_arr = new A[10];

	delete []p_arr;

	int *p_Iarr = new int[10];

	delete p_Iarr;

	B *p_B = new B();

	delete p_B;

	B *p_Barr = new B[10];

	delete []p_Barr;

	A *p_A = new A();

	delete p_A;
	
	return 0;
}

</pre><p></p><p></p><pre>


上面的图是new int(45);的内存数据,在哨兵位之间为这个int值。直接使用了delete


上面的图是new A[10];的内存数据,与其他不同的是我们定义了类A的析构函数,特别需要注意的是紫色标记的部分,分配对象数组的时候在真正数据之前还分配了4个字节的内存来保留数组元素的个数,在delete[]的时候取出这个数值就知道需要调用多少次析构函数。程序结束后打印了10次destructor..。这个必须使用delete[],如果使用delete,程序将就会crash.


上面的图是new int[10];的内存数据,这个也是new数组,与上面不同的是,对于内置类型int不需要调用析构函数,所以分配内存时就不需要多那个4个字节存数组元素个数。在这里我使用了delete,是可以的。使用delete[],也是可以的。


上面的图是new B();的内存数据,是单个对象,使用了delete。不需要多解释,主要看下面,与下面的数据做个比较。


上面的图是new B[10];的内存数据,是对象数组,与第二个不同的是,在类B中我们没有自定义他的析构函数,在分配内存的时候我们可以看到内存中也没有多分配那4个字节去存储数组元素个数。这里我们使用了delete[],事实上直接使用delete也是可以的。

由上面的几个数据分析我们可以得出结论:

1. new/delete、new[]/delete[] 配套使用总是没错的!

2. delete[]适用于带自定义析构函数的对象数组,如果没有自定义析构函数(在内存方面,析构函数主要用于释放对象中其他已分配的内存)也可以使用delete。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值