动态内存管理:malloc和free以及new和delete的联系与区别

文章目录

  • 动态内存管理:malloc和free以及new和delete的联系与区别
    • 一、 C/C++中程序内存区域划分:
    • 二、C语言中动态分配内存管理方式:
    • 三、C++内存管理方式
    • 四、malloc/free与new/delete的区别:

一、 C/C++中程序内存区域划分:

1. 内核空间:Linux系统对自身进行了划分,一部分核心软件独立于普通应用程序,运行在较高的特权级别上,它们驻留在被保护的内存空间上,拥有访问硬件设备的所有权限,Linux将此称为内核空间
2. 栈:又叫堆栈,非静态局部变量和函数参数及返回值都在栈上存储,栈是重上往下增长的。
3. 内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库,用户可以使用系统接口创建共享共享内存,做进程间通信
4. 堆:用于程序运行时动态分配内存,堆是从下往上增长的
5. 数据段:存储静态数据和全局变量
6. 代码段:可执行时的代码和只读常量。

具体如下图:

二、C语言中动态分配内存管理方式:

  • malloc:

  • 原型:

void *malloc(int byte_size);
  • 作用:动态开辟byte_size个字节的内存空间,不进行初始化,返回指向此内存的指针,此指针所指数据类型没有确定,需要强转

举例:

int *p=(int *)malloc(5*sizeof(int));
  • 例解:动态开辟5*4=20个字节大小的空间,返回空间首地址指针并强转为int *型后赋予指针变量p。

注意:malloc只开辟空间,不初始化,即只将此空间由未占用状态变为已占用状态,空间内存储的具体数据未指定改变。函数返回值是空间首地址,上例中赋给了p变量。

  • calloc:

  • 原型:void *calloc(int n,int type_byte_size);

  • 作用:动态开辟n*type_byte_size个字节,将每个字节均初始化为ascii码0,返回指向此内存的指针,此指针所指数据类型没有确定,需要强转。

举例:int *p=(int *)calloc(5,sizeof(int));

例解:动态开辟5*4=20个字节大小的空间,其中每个字节均赋初值0,返回空间首地址指针并强转为int *型后赋予指针变量p。

  • 注意:calloc在malloc的基础上将空间按字节初始化为ascii码0,且其参数有两个,两参数之积为空间总字节数。

realloc:

原型:

void *realloc(void *p,int byte_size);
  • 作用:对空间进行调整,若p为空,则该函数与malloc相同
  • 若p所指空间连续大小(单位字节)大于byte_size,则从首地址开始连续地扩充开辟p所指空间至byte_size字节,不对空间再次赋值,将空间地址指针返回;
  • 若p所指空间连续大小小于byte_size,则新开辟byte_size字节大小的空间,将p指向的空间内的数据复制进新空间,之后释放p所指空间(此时p为NULL),返回指向新空间的指针,此指针所指数据类型没有确定,需要强转。

举例:

int *p=(int *)calloc(5,sizeof(int));
p =(int*)realloc(p,10*sizeof(int));
  • 例解:首句中p为5*4=20字节的空间指针并按字节初始化为ascii码0,(int*)强转后才限定了指向空间的每个元素为int型。

  • 后句将p所指空间扩充为10*4=40字节的空间指针,未对其二次赋值,故此时p[0]~p[4]为0,p[5]~p[9]未初始化

注意:realloc的第一个参数必须是动态开辟的地址,不能是静态定义的数组的地址,结构体数组也不行。

  • free:
  • C 库函数 *void free(voidptr)** 释放之前调用 calloc、malloc 或 realloc所分配的内存空间
  • ptr-- 指针指向一个要释放内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果传递的参数是一个空指针,则不会执行任何动作。
  • 该函数不返回任何值

下面的实例演示了 free() 函数的用法:

 #include <stdio.h>int main()
{   char *str;    /* 最初的内存分配 */   str = (char *) malloc(15);   strcpy(str, "jikexueyuan");   printf("String = %s,  Address = %un", str, str);   /* 重新分配内存 */   str = (char *) realloc(str, 25);   strcat(str, ".com");  printf("String = %s,  Address = %un", str, str);   /* 释放已分配的内存 */   free(str);   return(0);}

让我们编译并运行上面的程序,这将产生以下结果:

String = jikexueyuan, Address = 355090448String = jikexueyuan.com, Address = 355090448

三、C++内存管理方式

  • new/delete操作内置类型:
void Test()
{// 动态申请一个int类型的空间int* ptr4 = new int;// 动态申请一个int类型的空间并初始化为10int* ptr5 = new int(10);// 动态申请10个int类型的空间int* ptr6 = new int[3];delete ptr4;delete ptr5;delete[] ptr6;
}

注意:申请和释放单个元素空间,使用new/delete操作符,申请和释放连续元素空间,使用new[]/delete[]操作符。

  • new/delete操作自定义类型:
class Test
{public:Test(): _data(0){cout<<"Test():"<<this<<endl;}~Test(){cout<<"~Test():"<<this<<endl;}
private:int _data;
};void Test2()
{// 申请单个Test类型的空间Test* p1 = (Test*)malloc(sizeof(Test));free(p1);// 申请10个Test类型的空间Test* p2 = (Test*)malloc(sizoef(Test) * 10);free(p2);}
void Test2()
{// 申请单个Test类型的对象Test* p1 = new Test;delete p1;// 申请10个Test类型的对象Test* p2 = new Test[10];delete[] p2;
}

注意:在申请自定义类型空间时,new会调用类的构造函数,delete会调用类的析构函数,malloc和free不会调用

  • new和delete的实现原理:

  • a、如果申请的是内置空间

  • 那么new/delete,malloc/free就没有太大区别。

  • 不同的地方主要有如果malloc申请空间失败,则会返回NULL,所以在用之前要进行判空处理。

  • 而new操作符申请空间时,如果失败,就会优先进行调整,若没有调整操作,就会抛出异常。

  • b、如果申请的是自定义空间:

  • new的原理为:

  • 首先调用operator new函数申请一个空间,而operator new函数则采用循环的方式,用malloc来进行申请空间

  • 若申请空间失败,就会优先进行调整操作,直到申请成功,若没有调整操作,就会抛出异常。

  • 注意此时并没有申请成功,只是相当于申请了以个大小相同的空间而已,此时该对象是不完整的

  • 所以最后进行的操作是在申请的空间上执行类的构造函数,完成对象的构造。

  • delete的原理为:

  • 首先为了防止内存泄漏,在该空间上执行类的析构函数,完成对象资源清理工作,最后调用operator delete函数,释放该对象的空间。

  • new[N]的原理为:

  • 调用operator new[] 函数,而在operator new[]中实际调用operator new函数完成对N个对象空间的申请操作,最后在申请的空间上执行N次构造函数,完成对N个对象的申请。

  • delete[]原理为:

  • 在申请的空间上执行N次析构函数,完成对N个对象的资源清理工作,最后在调用operator delete[] 函数,而在operator delete[]函数中实际调用operator delete函数完成对N个对象空间的释放回收操作。

四、malloc/free与new/delete的区别:

malloc/free new/delete
是标准库内的函数 是关键字,不是函数
malloc申请的空间不会初始化 new出来的空间可以初始化
malloc申请空间时,需要手动计算申请空间的大小并传递 new不需要,只需在后面跟空间的类型
malloc的返回值为void*,所以在使用时要进行强转操作 new后跟的就是空间的类型
malloc申请空间失败会返回NULL,所以使用时需要判空 new申请空间失败会抛出异常
在申请自定义空间时,malloc/free只负责开辟空间,和释放空间,不会调用构造函数和析构函数 new会在申请空间后调用构造函数完成对象的初始化,delete会在释放空间前调用析构函数完成资源清理工作。

动态内存管理:malloc和free以及new和delete的联系与区别相关推荐

  1. C语言-动态内存管理(malloc()、calloc()、realloc()、free())

    C语言 动态内存分配 文章目录 C语言 动态内存分配 前言 一.为什么存在动态内存分配? 二.动态内存函数的介绍 1.初识malloc()和free() 2.malloc()和free()的简单使用 ...

  2. 动态内存管理 - malloc、calloc、realloc、柔性数组

    目录 一.为什么存在动态内存分配 二.动态内存函数的介绍 1.1 malloc 1.2 free 1) 动态开辟多少个字节的内存空间,返回该空间的起始地址:且开辟的空间使用方法,类似于数组,是一块连续 ...

  3. C ++ 内存 | C/C++的动态内存管理_1

    C/C++的动态内存管理 1. C语言中,我经常会用到动态内存管理的三个命令: malloc calloc rolloc free (1)malloc 用来申请head内存空间的内存. (2)call ...

  4. C++---动态内存管理

    C/C++内存分布 栈:存储非静态局部变量.函数参数.返回值. 内存映射段:动态库. 堆:程序运行时动态内存分配. 数据段:存储全局变量.静态数据. 代码段:可执行代码,只读常量. C语言中动态内存管 ...

  5. C和C++安全编码笔记:动态内存管理

    4.1 C内存管理: C标准内存管理函数: (1).malloc(size_t size):分配size个字节,并返回一个指向分配的内存的指针.分配的内存未被初始化为一个已知值. (2).aligne ...

  6. C语言之动态内存管理与动态内存函数

    文章目录 一.为什么存在动态内存分配? 二.动态内存函数的介绍 1.malloc和free 2.calloc函数 3.realloc函数 一.为什么存在动态内存分配? 学习动态内存的管理方法之前,我们 ...

  7. LwIP 之五 详解动态内存管理 内存堆(mem.c/h)

    写在前面   目前网上有很多介绍LwIP内存的文章,但是绝大多数都不够详细,甚至很多介绍都是错误的!无论是代码的说明还是给出的图例,都欠佳!下面就从源代码,到图例详细进行说明.   目前,网络上多数文 ...

  8. C++ 动态内存管理:c/c++的动态内存管理,new/delete,operator new/delete,placement-new, 内存泄漏

    c/c++的动态内存管理 new/delete opeartor new/delete placement-new 内存泄漏 c/c++的动态内存管理 在开始之前首先要了解c和c++的内存分布,我简单 ...

  9. C语言程序设计 | 动态内存管理:动态内存函数介绍,常见的动态内存错误,柔性数组

    动态内存管理目录: 动态内存函数的介绍 常见的动态内存函数的错误 柔性数组 为什么会有动态内存管理呢 我们在日常使用中,创建一个数组,一个变量时都会开辟空间 如: int a; //在栈上开辟一个四字 ...

最新文章

  1. 去掉easyui datagrid内部虚线的方式。
  2. java中native_java中的native关键字
  3. Qt中槽函数触发两次的两种场景分析
  4. 【剑指offer】面试题35:复杂链表的复制(Java)
  5. 防御 | 阻止木马侵入(电脑设置)
  6. 圣经是上帝所默示和启示的
  7. docker 错误:Error response from daemon: cannot stop container: connect: connection refused: unknown...
  8. linux 手动 创建数据库连接,Linux下手动创建Oracle数据库过程
  9. LuaProfiler:Lua内存优化工具教程
  10. 谷歌浏览器将网页保存为图片或者pdf
  11. TeX Live 2021 从卸载到安装指南
  12. Redis运行时突然不能读取数据了
  13. 计算机网络中的网卡作用
  14. 模拟题 czy的后宫
  15. 计算机网络教室学生守则,高中计算机网络教室公益性开放管理制度
  16. 程序员的浪漫之——情侣日常小程序
  17. 基于VHDL的毛刺信号消除
  18. 制作openstack离线 yum 源
  19. 分享一个目前还支持离线下载的网盘
  20. hp ux安装mysql5.1.56_详细讲解Linux环境下MySQL5.1安装步骤

热门文章

  1. Java官方相关资源文件的获取教程
  2. eclipse中快捷键
  3. Java中的CopyOnWrite
  4. glyphicon halflings regular ttf 报错
  5. 悬崖边上的舞者,记7.2生产数据库灾难事件
  6. CodeForces - 1529F It‘s a bird! No, it‘s a plane! No, it‘s AaParsa!(最短路+思维建图)
  7. CodeForces - 1453D Checkpoints(概率+构造)
  8. 2020ICPC(小米邀请赛2) - Knapsack(贪心+dp)
  9. 布林通道参数用20还是26_“布林强盗”量化交易系统,它真正厉害的地方是在这里...
  10. max日期最大值为0_excel函数技巧:MAX在数字查找中的应用妙招