您的位置:首页 > 健康 > 养生 > C/C++内存管理

C/C++内存管理

2024/12/23 1:50:02 来源:https://blog.csdn.net/m0_52602233/article/details/140318438  浏览:    关键词:C/C++内存管理

本文目录

  • 1. C/C++的内存分布
    • 1.1 分辨
    • 1.2 sizeof与strlen区别
  • 2. C的内存管理
  • 3. C++的内存管理
    • 3.1 new与delete、delete[]
    • 3.2 operator new与operator delete
  • 4. malloc/free与new/delete区别
  • 5. 内存泄露
    • 5.1 分类
    • 5.2 避免内存泄露

1. C/C++的内存分布

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);
}

1.1 分辨

四个选项:栈、堆、静态区/全局区(数据段)、常量区(代码段)。

globalVar在哪里? 静态区
staticGlobalVar在哪里?静态区
staticVar在哪里?静态区
localVar在哪里?
num1 在哪里?

char2在哪里?
*char2在哪里?
pChar3在哪里?
*pChar3在哪里?常量区
ptr1在哪里?
*ptr1在哪里?

在这里插入图片描述

  1. 内核空间:用户代码不能读写;
  2. 栈区:又叫堆栈,栈是向下增长的(从高地址到低址值向下使用);
  3. 内存映射段:文件映射、动态库、匿名映射;
  4. 堆区:程序运行时动态内存分配,可以向上增长。
  5. 数据段:存储全局变量和静态变量;
  6. 代码段:存储可执行代码和常量。

1.2 sizeof与strlen区别

sizeof(num1) 40
sizeof(char2) 5
strlen(char2) 4
sizeof(pChar3) 4或8
strlen(pChar3) 4
sizeof(ptr1) 4或8

sizeof计算内存存储大小;strlen计算字符串长度,不包含\0。

2. C的内存管理

申请内存:malloc、calloc、realloc;
释放内存:free

面试题:

  1. malloc、calloc、realloc区别是什么?
    malloc仅仅是申请一块内存;
    calloc底层调用malloc申请一块内存,但还会额外对变量进行默认初始化;
    realloc在原申请的内存基础上进行内存扩容,如果后面的内存空间够,则原地扩容;
    后面的内存空间不够,则异地扩容,返回新的内存地址。

  2. malloc实现原理
    这个太难了,先不研究。

3. C++的内存管理

C++可以继续使用C的malloc、calloc、realloc和free,C的内存管理使用起来很麻烦,C++有自己的内存管理方式,使用起来很方便。

3.1 new与delete、delete[]

  1. new和delete都是操作符,new申请内存,delete/delete[]释放内存。
int* pa = new int;
int* pb = new int(12); // 动态申请内存并初始化
int* pArr = new int[10]; // 动态申请40个字节内存空间
delete pa;
delete pa;
delete[] pArr;
  1. 申请/释放单个不连续的内存使用new和delete,申请/释放多个连续的内存使用new[]和delete[]。
  2. new[]和delete[]底层多次调用new和delete完成申请或释放内存。

3.2 operator new与operator delete

  1. operator new和operator delete是C++提供的全局函数;
  2. new和delete是操作符,new和delete调用它们俩完成申请和释放内存;
  3. operator new实际是通过malloc来申请内存,operator delete最终也是通过free来释放内存。

4. malloc/free与new/delete区别

  1. new/delete对于自定义类型申请空间,会调用构造函数(new之后)和析构函数(delete之前),而malloc/free做不到。
  2. 对于内置类型,两者除了使用上有差别,效果一样。
  3. malloc/free是函数,new/delete是操作符。
  4. new申请内存失败会抛异常,malloc申请失败返回NULL。
  5. malloc申请的内存空间不会默认初始化,new会。
  6. malloc申请内存需要计算并传递内存大小,new不需要。
  7. malloc返回值是void*,接收时需要强转成需要的类型,new的返回值不需要强转。

5. 内存泄露

内存泄露:程序未能释放不再使用的内存。

不是指物理上的消失,而是因为这块内存不再使用,程序失去对这块内存的控制,造成内存浪费。对于长期运行的程序而言,如服务器、操作系统,内存泄漏造成的影响很大,最终程序响应越来越慢,导致机器卡死,所以及时释放不需要再使用的内存至关重要。

需要注意的是避免内存泄露的同时,也要避免使用野指针。

5.1 分类

  1. 堆内存泄露(Heap Leak):malloc/calloc/realloc/new申请的内存没有被free/delete。
  2. 系统资源泄露:程序使用系统分配的资源,如套接字、文件描述符、管道等,之后没有使用对应的函数释放资源。

5.2 避免内存泄露

  1. 检测内存泄漏:VS环境下使用Windows提供的_CrtDumpMemoryLeaks()函数,会提示泄露多少字节,但没有准确的位置信息。
  2. 内存泄露检测工具:很多工具都不靠谱。Linux下几款C++程序中的内存泄露检查工具 ----- 内存泄露检测工具比较
  3. 事前预防:最理想的情况,有良好的编码习惯,使用智能指针等。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com