跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

C++内存模型演示:代码、原理与注意事项

通过C++代码演示内存模型,展示栈、堆、全局/静态区、常量区及代码区的变量地址分布。解释了各区域的分配方式、生命周期及特点,并强调了堆内存泄漏、野指针、栈溢出等关键注意事项,帮助理解C++内存管理机制。

女王发布于 2026/3/30更新于 2026/7/1846 浏览

C++内存模型演示:代码、原理与注意事项

本文通过一段带详细注释的C++代码,结合内存区域划分(栈、堆、全局/静态区、常量区、代码区),直观解释C++的内存模型。代码运行后会打印各变量的内存地址,通过地址分布可清晰区分不同内存区域,同时附带核心原理说明与关键注意事项。

一、C++内存模型演示代码

#include <iostream>
#include <cstdlib> // 用于 malloc/free
using namespace std;

// 1. 全局变量:存放在【全局/静态存储区】(程序启动时分配,结束时释放)
int global_var = 10;
// 2. 静态全局变量:同样存放在【全局/静态存储区】,仅当前文件可见
static int static_global_var = 20;
// 3. 全局常量:存放在【常量存储区】(只读,不可修改)
const int const_global_var = 30;

// 函数:存放在【代码区】(只读,存放指令)
void test_memory(int param){
    // param:函数参数,存放在【栈】
    // 4. 局部变量:存放在【栈】(自动分配,函数执行完自动释放)
    int local_var = 40;
    // 5. 静态局部变量:存放在【全局/静态存储区】(仅初始化一次,生命周期贯穿程序)
    static int static_local_var = 50;
    // 6. 局部常量:存放在【栈】(C++11后可能优化到常量区,但本质是局部作用域)
    const int const_local_var = 60;

    cout << "=== 函数内部变量(test_memory)===" << endl;
    cout << "函数参数(栈): param = " << param << ", 地址 = " << &param << endl;
    cout << "局部变量(栈): local_var = " << local_var << ", 地址 = " << &local_var << endl;
    cout << "静态局部变量(全局/静态区): static_local_var = " << static_local_var << ", 地址 = " << &static_local_var << endl;
    cout << "局部常量(栈): const_local_var = " << const_local_var << ", 地址 = " << &const_local_var << endl;

    // 7. 堆内存分配:通过 new 手动分配,存放在【堆】(需手动释放,否则内存泄漏)
    int* heap_var1 = new int(70); // 堆上分配单个 int
    int* heap_var2 = new int[3]{80, 90, 100}; // 堆上分配数组

    cout << "\n=== 堆内存(手动分配)===" << endl;
    cout << "堆变量 1(new int): *heap_var1 = " << *heap_var1 << ", 地址 = " << heap_var1 << endl;
    cout << "堆数组(new int[]): heap_var2[0] = " << heap_var2[0] << ", 地址 = " << heap_var2 << endl;

    // 堆内存释放:必须手动 delete,否则程序结束前不会释放(内存泄漏)
    delete heap_var1; // 释放单个堆变量
    delete[] heap_var2; // 释放堆数组(注意加 [])
    heap_var1 = nullptr; // 避免野指针
    heap_var2 = nullptr;
}

int main(){
    cout << "=== 全局/静态存储区 & 常量区 ===" << endl;
    cout << "全局变量:global_var = " << global_var << ", 地址 = " << &global_var << endl;
    cout << "静态全局变量:static_global_var = " << static_global_var << ", 地址 = " << &static_global_var << endl;
    cout << "全局常量:const_global_var = " << const_global_var << ", 地址 = " << &const_global_var << endl;

    // 调用函数,演示栈、堆
    test_memory(100); // 实参 100 会被拷贝到形参 param(栈上)

    // 演示栈溢出(可选,取消注释运行会崩溃)
    // void stack_overflow() { stack_overflow(); } // 递归过深,栈空间耗尽
    // stack_overflow();

    return 0;
}

二、代码编译与运行

以下为 Linux/macOS环境下的编译运行命令,Windows环境(MinGW)编译命令相同,运行时替换为 memory_demo.exe 即可。

# 编译
g++ memory_demo.cpp -o memory_demo
# 运行
./memory_demo

三、典型运行输出

说明:以下地址仅为示例,不同系统、编译器运行结果略有差异,但各内存区域的地址分布规律一致。

=== 全局/静态存储区 & 常量区 ===
全局变量:global_var = 10, 地址 = 0x564b8e7a2044
静态全局变量:static_global_var = 20, 地址 = 0x564b8e7a2048
全局常量:const_global_var = 30, 地址 = 0x564b8e7a1f04
=== 函数内部变量(test_memory)===
函数参数(栈): param = 100, 地址 = 0x7ffd2b3c4aac
局部变量(栈): local_var = 40, 地址 = 0x7ffd2b3c4aa8
静态局部变量(全局/静态区): static_local_var = 50, 地址 = 0x564b8e7a204c
局部常量(栈): const_local_var = 60, 地址 = 0x7ffd2b3c4aa4
=== 堆内存(手动分配)===
堆变量 1(new int): *heap_var1 = 70, 地址 = 0x564b8e9f7eb0
堆数组(new int[]): heap_var2[0] = 80, 地址 = 0x564b8e9f7ed0
=== 常量存储区 ===
字符串常量(常量区): str_const = Hello, C++ Memory!, 地址 = 0x564b8e7a1f28

四、核心内存区域原理解释

通过代码输出的地址分布和变量特性,可明确 C++ 的 5 大内存区域,各区域核心信息如下表所示:

内存区域存放内容分配方式生命周期核心特点
代码区(Code)函数指令、编译后的机器码编译器自动分配程序启动到结束只读(防止指令被篡改),地址通常最低廉
常量区(RO Data)字符串常量、const 全局变量编译器自动分配程序启动到结束只读(修改会崩溃),地址与全局/静态区接近但独立
全局/静态区(Data/BSS)全局变量、static 变量(全局/局部)编译器自动分配程序启动到结束静态分配,仅初始化一次(static 局部变量不会随函数调用重新初始化)
栈(Stack)局部变量、函数参数、返回值编译器自动分配作用域内有效(函数执行完释放)空间小(通常几 MB),分配效率极高(栈指针移动),向下生长
堆(Heap)new/malloc 分配的动态内存程序员手动分配手动释放(delete/free)空间大(可到 GB 级),分配效率低(需查找空闲块),向上生长,容易内存泄漏

五、关键注意事项(代码中隐含的坑)

  • 堆内存泄漏:若忘记 delete(如注释掉 delete heap_var1),堆内存会一直占用,直到程序结束。长期运行的程序(如服务器)会因内存泄漏崩溃。
  • 野指针:delete 后未将指针置为 nullptr,指针仍指向已释放的堆地址,后续访问会导致程序崩溃(未定义行为)。
  • 栈溢出:递归过深、局部变量过多(如超大数组 int arr[1000000])会耗尽栈空间,触发栈溢出崩溃。
  • 常量区只读:字符串常量('Hello…')存放在常量区,试图修改(如 str_const[0] = 'h')会导致运行时崩溃。
  • static 局部变量:仅初始化一次,下次函数调用时保留上次的值(代码中 static_local_var 每次调用都是 50,不会重新赋值)。

六、总结

通过这段代码,可直观理解 C++ 内存的分配机制和各区域特性,这也是面试中高频考点(如堆与栈的区别、内存泄漏原因等)。实际开发中,合理管理堆内存、避免栈溢出、区分常量与变量的存储区域,是写出高效稳定代码的关键。

目录

  1. C++内存模型演示:代码、原理与注意事项
  2. 一、C++内存模型演示代码
  3. 二、代码编译与运行
  4. 编译
  5. 运行
  6. 三、典型运行输出
  7. 四、核心内存区域原理解释
  8. 五、关键注意事项(代码中隐含的坑)
  9. 六、总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Milvus 部署架构选型与 Linux Docker 实战指南
  • macOS 使用 n 管理 Node.js 版本解决权限问题
  • ClawX:OpenClaw 可视化桌面客户端,零配置玩转 AI 智能体
  • GitNexus 技术解析:基于知识图谱的代码库智能分析
  • Spring Boot 项目集成 GitHub Copilot 实战教程与避坑指南
  • 大模型应用开发核心技术与实践指南
  • 基于 Spring Boot 的农产品智慧物流调度系统设计
  • Buzz 离线语音转文字工具:Whisper 模型集成与使用指南
  • Java 项目构建与管理:Maven 核心实战指南
  • 深入理解注意力机制与 Transformer 模型实战
  • Spring Boot 电影院后台管理系统实战指南
  • MCP 插件实战:Browser Tools 集成指南
  • 2026 年 3 月全球 AI 前沿动态
  • TRAE 接入方舟 Coding Plan 配置教程
  • Java 版本选型:JDK 特性对比与实战建议
  • 位运算基础与经典算法题解析
  • LeetCode 原地复写零:双指针与逆向填充 O(n) 时间 O(1) 空间解法
  • VSCode 使用 Git 将代码上传至 Gitee 教程
  • 前端虚拟列表实现原理与优化实践
  • Bucket4j 速率限制库:Java 流量控制实战入门

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online