Skip to content

C++ 内存管理专题 ​

一句话总览 ​

C++ 面试「内存管理」覆盖:进程内存布局、堆与栈、malloc/free 与 new/delete、内存对齐、内存泄漏定位、以及虚拟内存。必须能讲原理,而不只是区别表。

问题清单(含答案) ​

内存布局 / 分配 ​

1. 进程虚拟地址空间如何分布?

答案

从低到高:代码段(.text)、只读数据(.rodata)、已初始化数据(.data)、未初始化(.bss)、堆(向上增长)、共享库/mmap 区、栈(向下增长)、内核空间。详见 layout.md。

2. C++ 的内存分区?

答案

代码区(函数指令)、全局/静态区(.data/.bss)、堆(new/malloc 动态分配)、栈(局部变量/函数调用)、常量区(.rodata)。

3. 堆和栈的区别?

答案

栈编译器自动管理、快、小(默认 8MB)、LIFO、连续;堆手动管理、慢、大、可碎片化、任意顺序。栈分配只移动栈指针,堆要走分配器。

4. new 在哪分配?失败怎么办?

答案

在堆上分配。失败默认抛 std::bad_alloc;new (std::nothrow) 返回 nullptr;也可设 new_handler 在失败时处理。

5. 栈上放不下用堆;栈大小限制多少?

答案

Linux 默认 8MB(ulimit -s 查看)。递归过深或大局部数组会栈溢出(stack overflow)。

malloc / new ​

6. malloc 和 new 的区别?

答案

malloc 只分配原始内存、返回 void*、需指定字节数、失败返 NULL、不调构造;new 分配 + 调构造函数、返回类型化指针、失败抛异常、operator new 可重载。详见 malloc-new.md。

7. delete 和 delete[] 的区别?

答案

delete 调一次析构;delete[] 调 N 次析构。所以 new[] 会额外存元素个数(通常前缀 8 字节)供 delete[] 读取——用错会 UB。

8. malloc 底层?

答案

小块走 brk(移动堆顶)、大块走 mmap;内部用 free list/bins 管理空闲块(glibc ptmalloc)。

9. malloc(1KB) vs malloc(1MB)?

答案

glibc 有 MMAP_THRESHOLD(默认约 128KB):小于走 brk 的堆、free 后留在进程里复用;大于走 mmap 单独映射,free 直接 munmap 还给系统,避免大块长期占用。

10. new 的实现分几步?

答案

① operator new 分配内存(可重载)② 调构造函数。placement new 在已有内存上构造(不分配);new_handler 在分配失败时被调用(可重试或抛异常)。

对齐 / 内存细节 ​

11. 什么是内存对齐?为什么?

答案

变量地址是其大小(或 alignas 指定值)的整数倍。原因:CPU 按对齐地址一次访存更快,未对齐可能跨 cache line/两次访存、部分平台直接异常。

12. 计算 sizeof(Struct)?

答案

按最大成员对齐,成员按声明顺序排、中间补 padding 到各自对齐边界,末尾再补到整体对齐。经典手算题见 alignment.md。

泄漏 / 排查 ​

13. 内存泄漏怎么检测/避免?

答案

检测:valgrind(memcheck 报泄漏+未初始化读)、ASan(编译插桩,退出时报)、mtrace。避免:RAII/智能指针、用容器、明确所有权。详见 leak.md。

14. 程序崩溃 → core dump 怎么定位?

答案

开启 core(ulimit -c unlimited),崩溃后用 gdb ./prog core 加载,bt 看调用栈。详见 debugging/crash-debug.md。

子文档 ​

文件内容
index.md本文件
layout.md进程/虚拟内存布局、堆栈对比
malloc-new.mdmalloc/new/delete/free 区别与底层
alignment.md内存对齐与 sizeof 手算
leak.md泄漏检测与避免

糌粑的面经笔记 · VitePress 版