C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ 进程内存布局

C++程序的进程内存布局的实现

作者:华丽的周遭

本文主要介绍了C++程序的进程内存布局的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在Linux环境下,C++程序的进程内存布局遵循经典的分段模型,各段按功能划分并拥有不同的访问权限。理解这一布局对内存管理、性能优化及问题排查(如内存泄漏、越界访问)至关重要。

一、通用进程内存布局(Linux/x86_64为例)

进程的用户空间内存(32位通常为0~3GB,64位为0~128TB)从低地址到高地址依次划分为以下核心段(实际布局可能因编译器、链接器或系统配置略有差异):

1.代码段(Text Segment,.text)

作用:存储可执行指令(机器码)和只读数据(如字符串字面量、const全局变量)。

权限:只读(r-x),防止程序意外修改指令。

内容

特点:多个进程可共享同一份代码段(如动态库),节省内存。

2.数据段(Data Segment,.data)

作用:存储已显式初始化的全局变量和静态变量(包括static局部变量)。

权限:可读写(rw-)。

内容

特点:程序启动时由加载器从可执行文件中读取初始值,占用磁盘空间(因需保存初始值)。

3.BSS段(Block Started by Symbol,.bss)

作用:存储未显式初始化或初始化为0的全局变量和静态变量。

权限:可读写(rw-)。

内容

特点:不占用可执行文件的磁盘空间(仅记录大小),程序启动时由内核初始化为0。

4.堆(Heap)

作用:用于动态内存分配(如mallocnewcalloc)。

权限:可读写(rw-)。

生长方向:从低地址向高地址增长(与栈相反)。

管理机制:由内存分配器(如glibc的ptmalloc)管理,通过brk/sbrk系统调用扩展或收缩。

特点

5.栈(Stack)

作用:存储函数调用的上下文,包括:

权限:可读写(rw-)。

生长方向:从高地址向低地址增长。

特点

6.内存映射区域(Memory Mapping Segment,.mmap)

作用:用于文件映射(如mmap系统调用)、共享内存(shmget)或动态链接库(.so)的加载。

位置:通常在堆和栈之间(高地址侧靠近栈,低地址侧靠近堆)。

特点

7.内核空间(Kernel Space)

二、C++特有的内存布局细节

C++的对象模型、虚函数、模板等特性会在上述通用布局基础上增加特殊结构:

1.类对象的内存布局

普通成员变量:存储在栈(局部对象)或堆(动态对象)中,按声明顺序排列(考虑内存对齐)。

示例:

class MyClass {
    char c;    // 1字节(偏移0)
    int i;     // 4字节(偏移4,因对齐到4字节)
    double d;  // 8字节(偏移8)
};  // 总大小:1+3(填充)+4+8=16字节(64位系统)

静态成员变量:属于类而非对象,存储在数据段(已初始化)或BSS段(未初始化),所有对象共享同一实例。

示例:static int MyClass::count;存储在数据段或BSS段。

2.虚函数与虚函数表(vtable)

虚函数表(vtable):每个包含虚函数(或继承自含虚函数的类)的类会生成一个vtable,存储虚函数地址。vtable是只读数据,通常位于代码段(.rodata)或数据段(.data)。

虚指针(vptr):每个对象实例中会隐含一个vptr(通常位于对象内存的起始位置),指向所属类的vtable。

示例:

class Base {
public:
    virtual void func() {}  // 虚函数
    int x;
};
Base* obj = new Base();
// obj的内存布局:[vptr(8字节)] + [x(4字节)] + [填充(4字节,对齐到8字节)]

多态实现:通过对象的vptr找到vtable,再调用具体函数(如obj->func()时,实际调用vtable[0])。

3.继承与内存布局

4.临时对象与返回值优化(RVO/NRVO)

三、内存布局示意图(简化版,64位系统)

高地址
+----------------------+
|      内核空间         | (用户态不可访问)
+----------------------+
|         栈            | (向下增长:局部变量、返回地址)
|        ...            |
|        ↓              |
+----------------------+
|      内存映射区域       | (动态库、mmap文件、共享内存)
+----------------------+
|         堆            | (向上增长:malloc/new分配的内存)
|        ↑              |
|        ...            |
+----------------------+
|        BSS段           | (未初始化全局/静态变量,初始化为0)
+----------------------+
|       数据段           | (已初始化全局/静态变量)
+----------------------+
|       代码段           | (可执行指令、只读数据:.text/.rodata)
+----------------------+
低地址

总结

C++进程的内存布局是代码段、数据段、BSS段、堆、栈等的有机组合,C++特性(虚函数、继承、对象模型)在此基础上增加了vtable、vptr等结构。

到此这篇关于C++程序的进程内存布局的实现的文章就介绍到这了,更多相关C++ 进程内存布局内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文