C++ new和delete内存管理

目录

1、new和delete的含义

1)对基本类型的处理

2)对类的处理

new[]/delete[]和new/delete的工作原理

如果出现delete pT2

2、new/delete和malloc/free的区别和联系

​3、C++申请、释放内存的步骤

4、内存泄漏的几种情况

5、参考文献


 

1、new和delete的含义

new和delete是用来分配内存和释放内存的两个操作符。

1)对基本类型的处理

2)对类的处理

new[]/delete[]和new/delete的工作原理

1.Operator new[]的工作原理是会使用malloc函数一次性申请好此次操作+4个字节大小的内存空间,然后依据本次申请的对象数,循环调用数组内各个对象的构造函数。其所申请的内存结构如下:

2.Operator new 的工作原理,就是malloc对象所需大小的内存,然后调用对象的构造函数。它并没有在内存中记录数组的对象个数。

3.delete []的工作原理是先把参数向后偏移4个字节,得到后续元素个数,然后在一个循环中依次调用各元素的析构函数,最后再调用free()函数,其中传递给free的是偏移之后的地址。

4.delete 的工作原理很简单,调用参数的析构函数,然后在把这个地址无需偏移传递给free.

5.operator new [] 与delete[]成对出现;operator new 与delete成对出现。

class Test
{
public:
    Test(){};
    ~Test(){};
private:
    int a;
};

int main()
{
    //以下这两个new表达式,一个是分配一个对象,一个是分配对象数组。内部实现也是截然不同。
    Test* pT1 = new Test;//分配并初始化一个Test对象
    Test* pT2 = new Test[10];//分配10个默认初始化的Test对象

    delete pT1;
    delete[] pT2;
    
    return 0;
}

如果出现delete pT2

pT2指向的是数组内存块的第一个元素的起始地址,但它不是整个动态内存块的起始处,换句话说,pT2不是某次malloc的返回值,因而它无法被free处理,因为free只接受malloc一系列动态分配函数的返回值。

所以,当第一个~Test()被调用,程序会立马崩溃。

2、new/delete和malloc/free的区别和联系

  1. 它们都是动态管理内存的入口;
  2. 他们都是在堆上申请空间;
  3. malloc/free是C/C++标准库的函数,new/delete是C++操作符;
  4. malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造、析构函数进行初始化与清理(清理成员);
  5. malloc/free需要手动计算类型大小且返回值为void*,new/delete可自己计算类型的大小和返回对应类型的指针;
  6. new/delete的底层调用了malloc/free;
  7. malloc/free申请空间后得判空,new/delete则不需要;
  8. new直接跟类型,malloc跟字节数个数。

以一张动态内存分布图为例:

3、C++申请、释放内存的步骤

new和delete就像malloc和free一样,都要成对使用!

伪代码:

  1. xxx* p = new xxx;
  2. use p;
  3. delete/delete[] p;
  4. p = NULL;

4、内存泄漏的几种情况

(1)申请内存但并未释放。

void FunTest()
{
int *pTest1 = (int*)malloc(10*sizeof(int));
*pTest1 = 0;
}

(2)程序逻辑错误,这里引出两个问题。

①同一块空间释放两次,导致崩溃;

②有一块空间没有释放,以为释放了,导致内存泄漏。

void FunTest()
{
int *pTest1 = (int*)malloc(10*sizeof(int));
int *pTest2 = (int*)malloc(10*sizeof(int));

pTest1 = pTest2;

free(pTest1);
free(pTest2);
}

(3)程序的误操作,将堆破坏。申请的空间不足以赋值,释放导致崩溃。

void FunTest()
{
char *pTest1 = (char*)malloc(5);
strcpy(pTest1,"hello world");
free(pTest1);
}

(4)当释放时传入的地址和分配时的地址不一样时,会导致崩溃。

void FunTest()
{
int *pTest1 = (int*)malloc(10*sizeof(int));
assert(pTest1 != NULL);

pTest1[0] = 0;
pTest1++; //地址向后移动了一位
free(pTest1);
}

5、参考文献

非常推荐!

c++详解【new和delete】:https://blog.csdn.net/xxpresent/article/details/53024555

C++ new和delete的原理分析:https://blog.csdn.net/jmh1996/article/details/77647976

new/delete与new[]/delete[]实现机制:https://blog.csdn.net/weizhengbo/article/details/55681186

https://bbs.csdn.net/topics/380074973

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值