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进行修正.

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

相关推荐
汉克老师17 小时前
GESP6级C++考试语法知识(二十七、广度优先搜索(二、二维BFS))
c++·算法·图论·宽度优先·广度优先搜索·gesp6级·gesp六级
此生决int17 小时前
算法从入门到精通——位运算
数据结构·c++·算法·蓝桥杯
春栀怡铃声17 小时前
【C++修仙录02】筑基篇:vector 使用
开发语言·c++·算法
丁劲犇17 小时前
使用TraeAI开发Web页面测试MSYS2 ucrt64 Qt MCP服务器
服务器·前端·c++·qt·mcp
码小猿的CPP工坊18 小时前
C++跨平台开发之基于wxWidgets开发GUI程序简介-001
开发语言·c++
故事和你9118 小时前
洛谷-【动态规划1】动态规划的引入4
开发语言·数据结构·c++·算法·动态规划·图论
wunaiqiezixin18 小时前
5.16周测
c++
学困昇18 小时前
Linux IPC 详解:匿名管道、命名管道、共享内存与信号量
linux·运维·服务器·c语言·c++·人工智能
计算机安禾18 小时前
【c++面向对象编程】第39篇:简单工厂模式与工厂方法模式:C++实现
c++·简单工厂模式·工厂方法模式