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

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

相关推荐
H Journey8 分钟前
C++ 强制类型转换
c++·类型转换
‎ദ്ദിᵔ.˛.ᵔ₎17 分钟前
map和set
c++
沐雪轻挽萤18 分钟前
15. C++17新特性-std::string_view
java·开发语言·c++
小小码农Come on32 分钟前
QML怎么使用C++多线程编程
开发语言·c++
沛沛rh451 小时前
用 Rust 实现用户态调试器:mini-debugger项目原理剖析与工程复盘
开发语言·c++·后端·架构·rust·系统架构
云栖梦泽1 小时前
Linux内核与驱动:13.从设备树到Platform平台总线
linux·运维·c++·嵌入式硬件
qeen871 小时前
【算法笔记】模拟与高精度加减乘除
c++·笔记·算法·高精度·模拟
txinyu的博客1 小时前
高并发内存池 - 简化版 tcmalloc
c++
少司府2 小时前
C++基础入门:内存管理
c语言·开发语言·c++·内存管理·delete·new·malloc
郝学胜-神的一滴2 小时前
从零起步:CMake基础入门与实战跨平台编译
c++·软件工程·软件构建·cmake