c++中为什么new[]和delete[]要配对使用

在学习c++内存管理时,学习new\[\]时,总是与delete配对使用,这是为什么呢?在内置类型无需析构的条件下情况下不能申请空间时用new\[\]而释放空间时用free吗?反正delete底层也是调用free,并且内置类型无需析构也不会造成内存泄漏.那不如我们实践一下吧.

首先我们先建立一个简单的类A,如下.因为类A里面没有申请空间,所以A不析构也不会造成内存泄漏.

cpp 复制代码
class A
{
public:
	A(int a = 0)
        :_a(a)
	{
		cout << "A(int a = 0)" << endl;
	}
	//~A()
	//{
	//	cout << "~A()" << endl;
	//}
private:
	int _a;
};

下面我们就来试一下用new\[\]来开空间,用free来释放吧

cpp 复制代码
int main()
{
	A* pa = new A[10];
	free(pa);

	return 0;
}

整体代码如下图

运行后结果见下

程序正常运行,没有崩溃.这是否说明可以不配对使用呢?

大家可能已经发现了,在上面我建立A类时把A的析构给屏蔽掉了,现在我们把A的析构放开,在进行上述实验.

整体代码如下

执行结果见下

这次竟然崩溃了,这是为什么呢?

从现象上来看是类里面是否显示写析构函数造成的影响,显示写了析构就会崩溃,不显示写句不会有事.

在进行调试后,内存窗口中在地址处输入pa,可看见下图结果从pa向后的40个字节也就是new的对象的空间都被正常初始化了

但是转到反汇编我们发现new这个语句开了48字节的空间.

这是什么原因呢?我们在去内存窗口看一下,向上条一行可以看到下图现象

可以看到new\[\]向前开了八个字节的空间去存储了new的对象的个数也就是0ah(10),可以概括成下图形式.记录这个对象个数是为了知道之后释放空间时要调用多少次的析构函数去析构new\[\]出来的对象.

而此时pa并没有指向开辟空间中的最前面,根据free()的要求,一块空间只能从头进行free不能从中间free所以出现了崩溃.

是否向前开辟空间储存对象个数取决于对象是否显示写析构函数,显示写析构了,编译器就认为释放空间时需要调用析构从而在前面多开一段空间去存储个数,如果没有显示写析构,则不用多开辟.这就是出现上面结果的原因.

在进行delete\[\] 时,内部会将pa指向的位置进行修正,修正后在进行free()的调用,所以不会出现问题. 但是delete和free都不会对pa进行修正.

综上,进行对空间的开辟和释放时函数要配对使用.

相关推荐
码匠许师傅15 分钟前
【C++三方组件】fmt:C++字符串格式化的前世今生
c++
anew___25 分钟前
舵机——让 Arduino 动起来
c++·stm32·单片机·嵌入式硬件·c
qq_3449205631 分钟前
Qt 鼠标双击QLabel全屏显示图像
c++·qt
f狐0狸x1 小时前
【C++修炼之路】C++继承的探索
c++·继承
虚无的纽扣1 小时前
【C++】C++11的魔法:不止右值引用,C++11赋予的编程神力
c++
码匠许师傅2 小时前
【C++三方组件】RE2:工业级正则的安全与性能
c++
ThornArmor2 小时前
《向内深潜,向外飞掠》
c语言·开发语言·c++·vim·visual studio
j7~2 小时前
【C++微服务项目开发脚手架】(环境篇)虚拟机 + Docker + MySQL/Redis/RabbitMQ/ES/etcd/FastDFS 全套配齐
linux·c++·ubuntu·docker·vmware·项目开发·微服务脚手架
qq_199886872 小时前
第5板块·第4节:性能优化中的高级技巧
c++·人工智能·gpu算力
郝学胜_神的一滴2 小时前
C++20模板元编程 04:变量模板 别名模板与模板Lambda实战
c++·visual studio