C++:1.内存模型划分

目录

1.内存模型逻辑划分

2.内存模型对应磁盘文件说明

3.程序加载过程


1.内存模型逻辑划分

在C++中,虚拟内存通常会被划分成5个区域,分别是堆、栈、全局/静态存储区、常量存储区、代码区。下面简单介绍下。

1.堆(heap)

在程序运行期间使用,用来存储动态分配的变量。C语言用malloc开辟堆空间、C++语言用new开辟堆空间。堆释放原则是,谁开辟,谁释放。如果不释放,就会造成内存泄漏,常见的OOM报错就是这种。如果没有释放,在程序结束后,操作系统会回收堆空间内存。

2.栈(stack)

栈是由编译器自动分配和释放,不需要程序员自行维护。像局部变量、函数传参都是存储在栈区。函数结束后,局部变量自动释放。

栈空间远小于堆,一般只有10MB左右。

3.全局静态存储区(.bss段和.data段)

有些叫全局区,有些叫静态区,有些甚至不在区分这么细了。其实叫什么无所谓,这两个都是在同一块内存中。存储的都是全局变量和静态变量。只是一个存储已经初始化的变量,一个存储未初始化的变量。

.bss段:存放未初始化的全局变量和静态变量。如 static int aa;

.data段:存放初始化了的全局变量和静态变量。如 static int aa = 100;

对于未初始化的全局变量和静态变量,程序启动后,编译器会默认赋予初始值。是int类型,就赋予0,字符串类型就赋予"",指针类型,就赋予nullptr。

4.常量存储区(.rodata段)

用来存储字符串常量、const修饰的常量。不能被修改。如

const char* str = "hello world"; // "hello world" 在常量区

const int MAX_NUM = 1000; // 全局const常量

5.代码区(.text段)

代码段也被称为文本区或只读区,存放程序的二进制代码,代码段是只读的,可以被多个进程共享。

2.内存模型对应磁盘文件说明

以Windows举例,程序编译好后,我们实际得到的是一个exe文件。里面存放的就是上面各个段的二进制内容。不过需要注意的是:.text/.rodata/.data/.bss这些内容会被打包到exe中,但堆和栈不会。他们不属于 exe 文件内容,是程序跑起来后才创建的内存。

3.程序加载过程

这一步就是第2步的反向过程。

操作系统加载exe时,会把文件内部的段映射到进程虚拟内存五大分区中。其中:

exe中的.text内容映射到内存代码区中,只读。

exe中的.rodata内容映射到内存常量存储区中,只读。

exe中的.data和.bss内容映射到内存全局静态存储区中,其中.bss在运行时会被清空,这也是为啥没有赋值的全局变量、静态变量也会有默认值而不是垃圾值的原因。可读写。

堆、栈,exe文件中不存在,是程序启动后操作系统自行创建的。

相关推荐
David猪大卫7 小时前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
HPtiger7 小时前
C++ 入门笔记:从 C 到 C++ 的核心过渡(命名空间、输入输出、缺省参数、重载、引用、内联)
c语言·c++·学习
努力努力再努力wz10 小时前
【Lua 进阶系列】从 C++ 对象到 Lua 变量:一文理解 userdata、Lua 栈与元表绑定机制
c++·junit·lua
慧都产品智能化11 小时前
Qt 表格升级攻略:复用已有编辑器,减少重复开发
c++·qt·编辑器·qt6.3
ShineWinsu11 小时前
对于Qt:QTableWidget常见属性以及QTableWidgetItem类的解析
开发语言·c++·qt·gui·客户端·表格·qtablewidget
ShineWinsu12 小时前
对于Qt:QListWidget常见属性以及QListWidgetItem类的解析
开发语言·c++·qt·客户端·列表·qlistwidget·qlistwidgetitem
坤坤子吖13 小时前
Linux网络编程:自定义应用层协议与 JSON 序列化
linux·服务器·网络·c++·笔记·json
沫璃染墨14 小时前
从零入门计算机网络系列(十八):TCP连接管理详解——从三次握手与四次挥手到TIME_WAIT机制
运维·服务器·网络·c++·网络协议·tcp/ip·tcp
自信1504130575915 小时前
重生之从0开始学习c++之——vector-中篇
c++·学习·算法
ShineWinsu18 小时前
对于Qt:QDial常见属性以及信号的解析
开发语言·c++·qt·gui·客户端·旋钮·qdial