C++内存管理(1):内存区域,new与delete

目录

对一些内存区域的理解

操作符new与delete

operator new与operator delete函数

malloc/free和new/delete的区别


对一些内存区域的理解

<1>栈:存储一些非静态局部变量,比如函数的形参,在函数里面创建的变量,返回值等。(向下增长)

<2>堆:动态分配内存的区域,需要手动申请,释放。比如malloc出来的空间就是在堆上开辟的。

<3>数据段(静态区):存储的是一些定义在全局的变量还有静态局部变量(static修饰的局部变量),比如在main函数里定义的int a,a这个变量就存在静态区。

<4>代码段(常量区):与上面几个区相比,常量区可以理解为存储的是数值(常量)而不是变量,比如在main函数里定义的int a=3,其中3这个数组就存在常量区里,还有一些const修饰的也属于常量区,比如const char* str="hello","hello"就存在常量区里。

下面给出具体场景进行解释:

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
    static int staticVar = 1;
    int localVar = 1;
    int num1[10] = { 1, 2, 3, 4 };
    char char2[] = "abcd";
    const char* pChar3 = "abcd";
    int* ptr1 = (int*)malloc(sizeof(int) * 4);
    int* ptr2 = (int*)calloc(4, sizeof(int));
    int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
    free(ptr1);
    free(ptr3);
}

上面各个变量存在哪里:

静态区:globalVar ,staticGlobalVar,staticVar。栈:localVar,num1 , char2,pChar3,ptr1, *char2常量区: *pChar3 堆:*ptr1。(重点理解*char2为什么在栈中而不是在常量区:事实上字符串"abcd"是存在常量区里,但是char2数组是在栈上开辟的,并且拷贝了字符串"abcd"的值,而*char2又是对char2数组解引用,拿到的是数组存储的首元素,所以是在栈上。)

操作符new与delete

<1>定义:new是用来动态开辟空间的操作符,与malloc不同的是,对于自定义类型会去调用它的构造函数。格式:new+"类型"+“[个数]”,若只申请一个可以不加“[ ]”。delete是用来释放动态开辟空间的操作符,对于自定义类型会去调用它的析构函数。格式:delete[ ]+变量名,若是释放只申请了一个的可以不加“[ ]”。(注意:对于没有默认构造的自定义类型如果没有给初始值会报错。)

<2>new开辟的空间如何初始化:如果是初始化单个,初始化的方式就是在后面加上“(初始化值)”,如果是初始化多个,就改用{ }即可。(注意:它支持隐式类型转换)

下面演示一下:

int* a=new int(1);//初始化。*1*
delete a;//*2*
int* b[3]=new int{1,2,3};//*3*
delete[] b;//*4*

//因为它支持隐式类型转换,所以以下情形是可以的
class A
{
public:
     A(int n)
     :_a(n)
     {}
private:
     int _a;
};
int main()
{
    A* pi=new int[3]{1,2,3};//隐式类型转换
    return 0;
}

注意:建议上面的*1*和*2*搭配使用,*3*和*4*搭配使用,否则容易有内存泄露问题(部分空间未释放)。

operator new与operator delete函数

operator new 和operator delete是系统提供的全局函数,operator new底层封装了malloc,与malloc只有一点不同:开辟失败不会返回NULL,而是抛异常;operator delete底层封装了free。

总结一下与new和delete的关系:operator new底层封装了malloc和抛异常功能,new底层则是调用operator new和构造函数。operator delete底层封装了free,delete底层是调用operator new和析构函数。

malloc/free和new/delete的区别

1. malloc和free是函数,new和delete是操作符

2. malloc申请的空间不会初始化,new可以初始化

3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可

4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理释放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值