【C/C++】 内存管理详解
2026/9/3 9:13:50 网站建设 项目流程


🔥铅笔小新z:个人主页
🎬博客专栏:C++学习
💫滴水不绝,可穿石;步履不休,能至渊。

C/C++ 内存管理详解:从入门到面试必备

大家好!今天我们来聊聊 C/C++ 中的内存管理,这是一个初学者容易迷糊、面试官又特别喜欢问的话题。内存管理理解好了,不仅能写出更稳定、更高效的程序,还能在面试中脱颖而出。我会尽量用大白话讲清楚,咱们一步步来。


一、C/C++ 程序的内存布局

我们先来看一个例子:

intglobalVar=1;// 全局变量staticintstaticGlobalVar=1;// 静态全局变量voidTest(){staticintstaticVar=1;// 静态局部变量intlocalVar=1;// 局部变量intnum1[10]={1,2,3,4};// 局部数组charchar2[]="abcd";// 局部字符数组constchar*pchar3="abcd";// 常量字符串指针int*ptr1=(int*)malloc(4*sizeof(int));// 动态分配}

这些变量分别存在哪里呢?

  • globalVarstaticGlobalVarstaticVar数据段(静态区)
  • localVarnum1char2
  • "abcd"(常量字符串) →代码段(常量区)
  • ptr1(指针变量本身) →
  • *ptr1(指向的内存) →

内存区域划分(图解)

高地址 → 内核空间(用户不可见) ↓ 栈(向下增长,存放局部变量、函数参数等) ↓ 内存映射段(文件映射、动态库、共享内存) ↓ 堆(向上增长,动态分配内存) ↓ 数据段(存放全局变量、静态变量) ↓ 低地址 → 代码段(存放可执行代码、常量)

二、C 语言动态内存管理:malloc / calloc / realloc / free

C 语言中动态内存管理靠这四个函数:

  • malloc(size):申请指定字节的内存,不初始化
  • calloc(num, size):申请num个大小为size的内存,并初始化为 0
  • realloc(ptr, size):调整已分配内存块的大小(可扩大或缩小)。
  • free(ptr):释放内存。

面试常问:

malloc / calloc / realloc 的区别?
答:

  • malloc只分配,不初始化;
  • calloc分配并清零;
  • realloc调整已有内存块大小,可能移动数据。

malloc 的实现原理?
答:glibc 中的malloc使用brk / sbrkmmap系统调用来管理内存,内部维护一个内存池和空闲链表,减少系统调用次数,提高分配效率。


三、C++ 内存管理:new / delete

C++ 引入了newdelete来更方便地管理内存,尤其是对于自定义类型

int*p1=newint;// 申请一个 intint*p2=newint(10);// 申请并初始化为 10int*p3=newint[10];// 申请 10 个 int 的数组deletep1;deletep2;delete[]p3;// 注意:数组用 delete[]

与 malloc / free 的最大区别:

  • new会调用构造函数,delete会调用析构函数。
  • malloc/free只负责内存分配和释放,不调用构造/析构。
classA{public:A(){cout<<"构造\n";}~A(){cout<<"析构\n";}};A*p1=(A*)malloc(sizeof(A));// 不调用构造A*p2=newA;// 调用构造free(p1);// 不调用析构deletep2;// 调用析构

四、operator new 与 operator delete

这两个是 C++ 内置的全局函数,newdelete底层就是调用它们:

  • operator new内部调用malloc,失败时抛出bad_alloc异常。
  • operator delete内部调用free

你可以重载它们,实现自定义内存管理(比如内存池)。


五、new / delete 的实现原理

1. 内置类型

malloc/free差不多,只是多了异常处理。

2. 自定义类型

  • new
    1. 调用operator new分配内存
    2. 调用构造函数初始化对象
  • delete
    1. 调用析构函数清理资源
    2. 调用operator delete释放内存

六、定位 new(placement-new)

如果你已经有一块内存(比如从内存池来的),想在这块内存上构造对象,可以用定位 new:

A*p=(A*)malloc(sizeof(A));new(p)A();// 在 p 指向的内存上调用构造函数p->~A();// 显式调用析构free(p);

常见用途:内存池、高性能内存管理。


七、malloc/free 与 new/delete 的区别(面试必背)

特性malloc / freenew / delete
类型函数操作符
初始化不初始化可初始化
大小计算需手动计算自动计算
返回值void*,需强转自动匹配类型
失败处理返回 NULL抛出异常
构造/析构不调用调用
适用对象内置类型内置+自定义类型

八、常见面试题扩展

  1. 内存泄漏怎么办?
    使用智能指针(unique_ptrshared_ptr)、RAII 机制,或工具如 Valgrind 检测。

  2. 什么是浅拷贝和深拷贝?
    浅拷贝只拷贝指针,深拷贝会拷贝指针指向的内容。动态内存必须深拷贝。

  3. 什么是内存对齐?
    计算机为了高效读写内存,要求数据地址是其大小的整数倍。#pragma pack可控制对齐方式。


九、总结

C/C++ 内存管理是编程基本功,理解清楚:

  • 内存布局:栈、堆、数据段、代码段
  • C 方式:malloc / calloc / realloc / free
  • C++ 方式:new / delete,支持构造析构
  • 区别:malloc 是函数,new 是操作符;new 会初始化、抛异常、调构造
  • 高级话题:operator new、定位 new、内存池

掌握这些,你不仅能写出更安全的代码,还能在面试中游刃有余。

如果这篇文章对你有帮助,欢迎点赞、收藏、转发!我们下期再见!


作者:铅笔小新z
日期:2025 年 12 月 2 日

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询