C++内存管理

本文详细解释了内存区域的划分(代码区、数据区、栈区和堆区),以及new和delete运算符在C++中的作用,包括动态内存分配、初始化、构造函数和析构函数的关联。特别指出new相当于operatornew(malloc)+构造函数,delete相当于operatordelete(free)+析构函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、内存区域

内存区域主要可以划分为四个区域:代码区、数据区、栈区、堆区。

代码区(常量区)存放函数体的二进制代码,这部分由操作系统进行管理。当程序运行结束后,这个区域会被释放。代码区是只读的,以防止意外修改代码。

数据区(或称为全局区、静态区)存放全局变量静态变量以及常量

栈区:由编译器自动分配和释放,主要存储函数的参数值、局部变量等。

堆区:由程序员分配和释放(如使用malloc、free、new、delete等函数)。

 简单来说,就是全局变量和静态变量存放在数据区,普通的变量在栈区,通过malloc、new申请的在堆区,可执行代码和可读常量在代码区。

接下来举几个容易混淆的例子来说明:

 

在这个例子中,a是全局变量,b是静态变量,所以它们在数据区,p、pc、arr很容易知道在栈区,那*p、*pc、*arr呢?

*p在堆区,因为是malloc出来的;*pc在代码区,我们要知道const char* pc实际上是针对所指向的内容,即*pc不可修改,既然*pc不可修改便是在代码区;*arr在栈区,指向栈区中的数组内容。

二、new/delete运算符

在C语言中我们向堆区申请空间是通过malloc来实现的,释放内存是通过free来实现的。而在C++中,提供了一个运算符new和delete来实现。

我们先来看看这两个运算符的用法:

int* pn = new int;//申请

delete pn;//释放

在C语言中我们需要写要申请的空间的字节数,但是在C++中就没有那么麻烦了,写类型就可以了,在上面两个语句中,便是申请了四个字节的空间并释放 。

对于基本数据类型数组的动态生成和释放:

int* parray = new int[size];//size根据需要的大小来写

delete [] parray;

 需要注意的是,要成对地写,否则可能会出错。

我们使用new来开辟空间时也是可以初始化的:

例如:

int* pn = new int(5); //初始化为5

int* parray = new int[10] {1,2,3,4,5};//与C语言中数组初始化类似,未给出的默认为0

对于基本数据类型,malloc与new并无太大差别,但是对于自定义类型差别就很大了。 

malloc只会分配内存,并不会初始化,但是new在分配内存的同时会调用构造函数初始化;在释放内存时,delete也会先调用对象的析构函数,然后再释放

 举个例子来看:

class A
{
private:
	int _a;
public:
	A(int x = 0)
		:_a(x)
	{}

};

int main()
{
	A* p = new A;
	delete p;
	return 0;
}

通过调试也可以看到确实走了构造函数,最后初始化为0了。 

malloc和new还有一点不同,使用new操作符时,如果申请内存失败了,会抛出异常,就避免了malloc时自己写if语句来检查。(下图来自文心一言)

new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

operator new和operator delete实际上与malloc和free是相同的。

可以理解为new = operator new(malloc)+构造函数,delete = operator delete(free)+析构函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值