9、C/C++ 内存管理详解:从基础到面试题

📘 C/C++ 内存管理详解:从基础到面试题

本文系统梳理了 C/C++ 中的内存分布、动态内存管理方式、new/delete 的底层原理,以及常见面试题,适合初学者和求职者参考。


🎯 本文目标

  • 理解 C/C++ 程序的内存分布结构
  • 掌握 C 语言中的动态内存管理函数:malloc / calloc / realloc / free
  • 掌握 C++ 中的 new / delete 操作符及其底层机制
  • 理解定位 new 表达式(placement-new)
  • 掌握常见面试题与内存泄漏检测方法

🧠 1. C/C++ 程序内存分布

C/C++ 程序运行时的内存通常分为以下几个区域:

区域 内容说明
栈(Stack) 局部变量、函数参数、返回地址等,向下增长
堆(Heap) 动态分配的内存,向上增长
数据段 全局变量、静态变量
代码段 可执行代码和只读常量
内存映射段 文件映射、动态库、共享内存等

📌 示例变量归属

cpp 复制代码
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(4 * sizeof(int)); // 栈(指针)+ 堆(数据)
}

🧮 2. C语言动态内存管理函数

✅ 函数说明

函数 功能
malloc 分配指定大小的内存,内容未初始化
calloc 分配并初始化为 0
realloc 重新分配内存大小
free 释放已分配的内存

📌 示例代码

cpp 复制代码
int* p1 = (int*)malloc(sizeof(int));
free(p1);

int* p2 = (int*)calloc(4, sizeof(int));
int* p3 = (int*)realloc(p2, sizeof(int) * 10);
free(p3); // 不需要再 free(p2)

🚀 3. C++ 的动态内存管理方式

C++ 提供了更高级的 new / delete 操作符,支持对象构造与析构。

✅ 基本用法

cpp 复制代码
int* ptr1 = new int;        // 分配一个 int
int* ptr2 = new int(10);    // 分配并初始化
int* ptr3 = new int[3];     // 分配数组

delete ptr1;
delete ptr2;
delete[] ptr3;

✅ 自定义类型支持构造/析构

cpp 复制代码
class A {
public:
    A(int a = 0) : _a(a) { cout << "构造:" << this << endl; }
    ~A() { cout << "析构:" << this << endl; }
private:
    int _a;
};

A* p1 = new A(1);
delete p1;

🔍 4. operator new 与 operator delete 原理

✅ operator new

底层通过 malloc 分配空间,失败时尝试调用 _callnewh(),最终可能抛出 bad_alloc 异常。

✅ operator delete

底层通过 free 释放空间,并进行内存块验证与线程锁保护。


⚙️ 5. new/delete 的实现原理

内置类型

  • newmalloc 类似,但 new 会抛异常,malloc 返回 NULL
  • deletefree 类似

自定义类型

  • new:调用 operator new → 构造函数
  • delete:析构函数 → 调用 operator delete
  • new[] / delete[]:分别调用构造/析构函数 N 次

📦 6. 定位 new 表达式(placement-new)

用于在已分配的内存上构造对象,常用于内存池。

cpp 复制代码
void* raw = malloc(sizeof(A));
A* obj = new(raw) A(10); // 构造对象
obj->~A();               // 手动析构
free(raw);

🎯 7. 常见面试题汇总

✅ malloc/free vs new/delete

对比项 malloc/free new/delete
类型 函数 操作符
初始化 不初始化 可初始化
类型安全 需强转 类型明确
错误处理 返回 NULL 抛异常
构造/析构 不调用 自动调用

🧨 内存泄漏详解

什么是内存泄漏?

程序未释放已分配但不再使用的内存,导致资源浪费。

危害

  • 程序响应变慢
  • 系统资源耗尽
  • 程序崩溃或卡死

示例

cpp 复制代码
int* p = new int[10];
// 忘记 delete[] p; 就会造成泄漏

🛠️ 如何检测与避免内存泄漏

检测方法

  • Windows:使用 _CrtDumpMemoryLeaks()
  • Linux:使用 Valgrind 等工具

避免方法

  • 良好编码规范
  • 使用智能指针(RAII)
  • 使用公司内部内存管理库
  • 使用专业检测工具

✅ 总结

C/C++ 的内存管理是系统编程的核心技能,理解内存分布、掌握动态分配与释放机制、熟悉构造与析构行为,是写出高质量代码的基础。面试中常考这些知识点,建议配合代码练习与工具使用深入掌握。

相关推荐
李白的粉6 小时前
基于springboot的新闻资讯系统
java·spring boot·毕业设计·课程设计·源代码·新闻资讯系统
麦麦鸡腿堡6 小时前
Java_LinkedList底层结构
java·开发语言
沐怡旸7 小时前
【穿越Effective C++】条款13:以对象管理资源——RAII原则的基石
c++·面试
whatever who cares7 小时前
android/java中gson的用法
android·java·开发语言
摇滚侠7 小时前
Spring Boot3零基础教程,为什么有Reactive-Stream 规范,响应式编程,笔记101
java·spring boot·笔记
一个不知名程序员www7 小时前
算法学习入门---二分查找(C++)
c++·算法
天天摸鱼的java工程师7 小时前
八年 Java 开发手敲:SpringBoot+SpringSecurity+JWT 实战,前后分离权限注解落地就能跑
java·后端
冰淇淋@7 小时前
idea启动项目报错java: OutOfMemoryError: insufficient memory
java·ide·intellij-idea
techzhi7 小时前
this view is read-only (IntelliJ IDEA)
java·ide·intellij-idea
编程学委7 小时前
Idea(2023版)使用Svn
java·svn·intellij-idea