[c++系列]c++中的动态内存管理

本文介绍了C++中的new和delete操作符在内存分配和释放中的作用,以及它们在自定义类型和内置类型上的差异。着重讨论了内存泄露的类型,包括堆内存泄露和系统资源泄露,并提出了事前预防(智能指针)和事后查错(泄漏检测工具)的解决策略。
摘要由CSDN通过智能技术生成

前言:

        c++的创始人为了解决一些自定义类型创建时候的初始化等问题,开创了new/delete新的操作符,所以下面我们主要围绕这两位新角色来展开。

首先我们得知道,有哪些内存的区域:

栈 ,堆,静态区(数据段),常量区(代码段),我们看下图:

 1.new和delete

1.1 内置类型情形

基本与c语言中的malloc,free等没有太大区别

1.2 自定义类型情形

1.new:调用operator new函数申请空间,在申请的空间上执行构造函数,完成对象的构造。

2.delete:在申请的空间上调用析构函数,将对象中的资源清理,然后调用operator delete来释放对象的空间。

3.new  A[N](A是某自定义类型的类名):实际上也是调用多次operator new来完成N个对象的空间申请;然后再申请的空间上执行N次构造函数

3. delete []:在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理, 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

(补充)1.3 operator newoperator delete函数

new和delete是操作符,系统提供了operator new operator delete两个全局函数(不是运算符重载):

        new实际底层调用operator new来申请空间,operator new实际也是调用malloc

        delete实际底层调用operator delete来释放空间,operator delete实际调用free

new实际上是调用 operator new函数,这个函数中有malloc和抛异常(当mallloc失败的时候,系统会自动提示异常,所以不用我们自己去写malloc的失败判断)

2 .new/delete和malloc/free不可混用

        对于一般的内置类型,new和free,不会出现问题;但是如果是自定义类型,则可能会出现问题。

我们举一个例子,如果是如下的代码:

stack *ptr=new Stack[10];
free(ptr);

        这种情况下,会报错,但不是因为没有对自定义类型调用析构函数二造成的内存泄露(内存泄漏一般不会被编译器检测到)导致的,而是在new T[n]开辟空间的时候,这个n是用来指示析构的次数的,内存会在原来首地址之前开辟一个空间来存储这个次数n。

         因为前面存储次数的空间没有释放,导致空间释放不完全,这才导致的报错。

但是尽管内存泄漏没有报错,我们依然要严格地处理来防止内存的泄露。

 3.内存泄露类型

1.堆的内存泄露

        堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new 等从堆中分配的一块存, 用完后必须通过调用相应的 free或者delete 删掉。
        假设程序的设计错误导致这部分内存没有被释放,那 么以后这部分空间将无法再被使用,就会产生Heap Leak。
2.系统资源泄漏
指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统 资源的浪费,严重可导致系统效能减少,系统执行不稳定。

内存泄漏非常常见,解决方案分为两种
1 、事前预防型。如智能指针等。
2 、事后查错型。如泄漏检测工具。

  • 24
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值