谈一谈c/c++程序的内存布局
2021/12/9 7:17:16
本文主要是介绍谈一谈c/c++程序的内存布局,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 内存布局
- 文本段
- 初始化数据段
- 未初始化数据段 (bss)
- 堆区
- 栈区
- 如何查看一个程序的内存布局
内存布局
一个C 程序的典型内存布局由以下几部分组成,
- 文本段
- 初始化数据段
- 未初始化的数据段(bss)
- 堆区
- 栈区
文本段
文本段也叫代码段,包含编译程序的机器码。通常文本段是可共享的,因此对于频繁执行的程序(例如文本编辑器、C 编译器、shell 等),只需要在内存中保留一个副本。可执行目标文件的文本段通常是只读段,以防止程序被意外修改。
初始化数据段
初始化数据段存储所有预先初始化的全局变量、静态变量、常量和外部变量(用 extern
关键字声明的变量),注意这部分存储的变量都是由程序员显式初始化过的,而不是由编译器初始化的。该段可以进一步分为只读初始化数据段和读写初始化数据段,
#include <stdio.h> /* global variable stored in Initialized Data Segment in read-write area*/ char c[]="rishabh tripathi"; /* global variable stored in Initialized Data Segment in read-only area*/ const char s[]="HackerEarth"; int main() { static int i=11; /* static variable stored in Initialized Data Segment*/ return 0; }
未初始化数据段 (bss)
在程序开始执行之前,该段中的数据被初始化为算术 0。未初始化的数据从数据段的末尾开始,包含所有初始化为 0 或在源代码中没有显式初始化的全局变量和静态变量。
bss - block started by symbol
#include <stdio.h> char c; /* Uninitialized variable stored in bss*/ int main() { static int i; /* Uninitialized static variable stored in bss */ return 0; }
堆区
堆是通常发生动态内存分配的段。当需要使用 malloc
和 calloc
函数分配更多内存时,堆会向上增长。 堆区由进程中的所有共享库和动态加载的模块共享。
malloc
和calloc
都是c
语言中的动态内存分配的函数,此外c语言中还可以使用realloc
函数重新分配内存(重新分配的内存与原内存相比,可大可小)。在c++中动态分配内存不是使用函数进行的,而是使用关键字new
.
#include <stdio.h> int main() { /* memory allocating in heap segment */ char *p=(char*)malloc(sizeof(char)); return 0; }
栈区
栈区用于存储所有局部变量,用于向函数传递参数以及函数调用结束后要执行的指令的返回地址(这样函数return
之后,能够接着之前的指令继续进行)。局部变量具有定义它们的块的作用域,它们是在控制进入块时创建的。所有递归函数调用都添加到堆栈中。
正是因为栈区的以上特点,我们可以看出在以下情况下,会发生栈溢出
- 局部变量太大 (这个大可能是真的有比较大的结构体变量,类对象,局部数组,或者太多的局部变量等等)
- 函数调用深度太深,这样我们的要返回执行的指令地址就要不停的压栈
- 同理,如果递归深度太深,也会造成压栈太多,从而栈溢出
要解决栈溢出的问题,我们的对应的方法是,将大的对象放在堆上;避免过深的调用;递归少用(如果必须要用,那一定要做深度限制)
栈和堆通常位于进程虚拟地址的两端,然后使用时不断的向中间靠拢,当两者相遇时,也就空间耗尽了。
以上80%的内容出自下边的文章,在翻译时做了部分修改,并且加入了自己的一些理解,若有兴趣可读原文。
https://www.hackerearth.com/practice/notes/memory-layout-of-c-program/
如何查看一个程序的内存布局
在windows下可以使用size命令查看程序的内存布局,
size .\VRS.exe
我们将得到以下返回值,
text data bss dec hex filename 615002 8704 0 623706 9845a .\VRS.exe
这篇关于谈一谈c/c++程序的内存布局的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升
- 2024-05-08代码报错不用愁,CodeGeeX一键完成代码修复、错误解释的功能上线了!
- 2024-05-08今天开始程序员不用再发愁写commit message了,全部由CodeGeeX自动完成!