底层知识
内容简介
底层知识用于解释程序如何从源码变成可执行文件,以及变量、函数、动态内存在运行时分别放在哪里。理解这些内容后,指针、生命周期、内存泄漏和悬挂指针会更容易理解。
用法
编译流程
源代码
-> 预处理
-> 编译
-> 汇编
-> 链接
-> 可执行文件常见含义:
- 预处理:处理
#include、宏、条件编译。 - 编译:把 C/C++ 代码转换成汇编或中间表示。
- 汇编:生成目标文件。
- 链接:把多个目标文件和库合成可执行文件。
常见内存区域
| 区域 | 主要内容 | 生命周期 |
|---|---|---|
| 代码区 | 程序指令 | 程序运行期间 |
| 全局/静态区 | 全局变量、静态变量 | 程序运行期间 |
| 常量区 | 字符串字面量、部分常量 | 程序运行期间 |
| 栈区 | 局部变量、函数参数、返回地址 | 随函数调用创建和销毁 |
| 堆区 | malloc/new 申请的内存 | 手动释放或由对象管理 |
int global_value = 1;
int main()
{
int local_value = 2;
static int static_value = 3;
int *heap_value = new int(4);
delete heap_value;
heap_value = nullptr;
return 0;
}最佳代码实践
- 不要返回局部变量的地址或引用。
- C++ 中优先用 RAII 管理堆资源,例如
std::vector、std::string、智能指针。 new和delete配对,malloc和free配对,不要混用。- 动态内存释放后把裸指针置空,减少误用概率。
错误用法
int* bad()
{
int value = 10;
return &value; // 错误:value 在函数返回后已经销毁
}int *p = new int(10);
free(p); // 错误:new 申请的内存必须 deleteint *p = malloc(sizeof(int));
*p = 10;
// 错误:忘记 free(p),产生内存泄漏注意事项
- “栈快、堆灵活”只是粗略说法,实际还要看对象大小、生命周期和所有权设计。
- 字符串字面量通常不可修改,不要用
char* p = "hello"; p[0] = 'H';。 - 内存地址的具体数值每次运行可能不同,不要依赖打印出来的地址。
相关:CandCpp指针、CandCpp预处理、RAII、智能指针
学习路径
- 上一节:CandCPP文件操作
- 当前阶段:CandCPP基础
- 下一节:cpp进阶