C程序执行的内存布局

6
我想知道内核如何为简单的 C 程序提供内存。
例如:
#include<stdio.h> 
#include<malloc.h> 
int my_global = 10 ; 
main() 
{ 
char *str ; 
static int val ; 
str = ( char *) malloc ( 100 ) ; 
scanf  ( "%s" , str ) ;
printf( " val:%s\n",str ) ;
free(str) ;
return 1 ;
}

在这个程序中,我使用了静态,全局和malloc来分配动态内存。 那么,内存布局会是什么样子的呢? 有人能给我一个URL链接,其中包含有关这个过程的详细信息吗?

my_globalval可能会被优化移除。 - kennytm
6
布局将部分取决于编译器/链接器,部分取决于操作系统。您需要明确指定是哪个。 - John Knoeller
5个回答

8
基本上,在针对 ELF(可执行和可链接格式)的 C 程序中,例如在 Linux 上构建的程序中,会创建一个标准的内存布局。其他架构可能存在类似的布局,但我不了解更多信息。
布局如下:
一些全局数据部分在内存中的低地址处进行初始化(例如当前执行代码、全局数据以及使用 C 代码中的 "..." 创建的任何字符串)。
在这之下是一个开放内存的堆,可以使用。随着对 malloc 和 free 的调用将所谓的“程序断点”移动到内存中较高的地址,此堆的大小会自动增加。
从内存中的高地址开始,栈向较低地址增长。栈包含任何本地分配变量的内存,例如在函数顶部或作用域内({ ... })的变量。
更多信息:

这里有一个关于运行 ELF 程序的良好描述链接1,以及有关格式本身的更多细节链接2。如果您想了解编译器如何将 C 代码转换为汇编代码的示例,可以查看 GCC,他们的内部手册中有一些有趣的内容;最相关的章节可能是第17章,特别是17.10、17.19和17.21。最后,英特尔公司在其IA-32体系结构软件开发人员手册中提供了大量有关内存布局的信息。它描述了英特尔处理器如何处理内存分段和堆栈等内容。虽然没有关于 ELF 的详细信息,但可以看到两者的匹配点。最有用的部分可能是第1卷的第3.3节:基本架构,以及第3章的第3A卷:系统编程指南,第1部分。

我希望这对于那些深入了解运行C程序内部的人有所帮助,祝你好运。


1

wikipedia上有一个简短的讨论。

稍微长一点的介绍在这里

更多细节可以在这里找到,但我不确定它的呈现方式是否很好。


1

所有静态和全局变量存储在数据段中,所有自动和临时变量存储在堆栈上,所有动态变量存储在堆上。

所有函数参数都存储在堆栈上,并且每个函数调用都有一个不同的堆栈帧,这就是递归函数的工作原理。

如需了解更多信息,请参见this site


0

0
  • 所有静态和全局未初始化变量都进入bss(符号块开始)。
  • 所有已初始化的全局/本地/静态变量进一步分为

只读

const int x = 10;

& 可读/可写

char Str [] =“StackOverFlow”

  • 堆栈段是存储局部变量的区域。所谓的局部变量是指在C程序中的每个函数中声明的所有变量,包括main()。

  • 文本段包含您的C程序的可执行指令,也称为代码段。这是程序步骤的机器语言表示,包括组成程序的所有函数,包括用户定义和系统函数。文本段是可共享的,因此对于不同的执行程序(例如文本编辑器,shell等),只需要在内存中有一个副本即可。通常,文本段是只读的,以防止程序意外修改其指令。

  • 程序的内存布局中还有一个未映射或保留的段,其中包含命令行参数和其他与程序相关的数据,例如可执行映像的较低地址-较高地址等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接