【问题标题】:C : Memory layout of C program executionC : C 程序执行的内存布局
【发布时间】:2010-03-20 07:04:35
【问题描述】:

我想知道内核如何为简单的 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 ;
}

看,在这个程序中,我使用了 static 、 global 和 malloc 来分配动态内存 那么,内存将如何布局……? 任何人给我 url ,其中将包含有关此过程的详细信息..

【问题讨论】:

  • my_globalval 可能会被优化移除。
  • 布局部分取决于编译器/链接器,部分取决于操作系统。您需要指定哪个。

标签: c


【解决方案1】:

基本上,在为 ELF(可执行和可链接格式)而构建的 C 程序中,例如那些在 linux 上构建的程序,会创建一个标准的内存布局。其他架构可能存在类似的布局,但我知道的还不够多,无法告诉您更多有关它们的信息。

布局:

有一些全局数据段在内存中的低内存地址初始化(例如当前执行代码的段、全局数据以及在 C 代码中使用 "..." 创建的任何字符串)。

下面有一堆可以使用的开放内存。随着对 malloc 和 free 的调用将所谓的“程序中断”移动到内存中的更高地址,此堆的大小会自动增加。

从内存中的高地址开始,堆栈向低地址增长。堆栈包含用于任何本地分配变量的内存,例如位于函数顶部或范围内的变量 ({ ... })。

更多信息:

here 对正在运行的 ELF 程序进行了很好的描述,the Wikipedia article 上有更多关于格式本身的详细信息。如果你想要一个编译器如何将 C 代码翻译成汇编的例子,你可以看看 GCC,他们的Internals Manual 里面有一些有趣的东西;最相关的部分可能是第 17 章中的部分,尤其是 17.10、17.19 和 17.21。最后,英特尔在其IA-32 Architectures Software Developer’s Manual 中有大量关于内存布局的信息。它描述了英特尔处理器如何处理内存分段和堆栈的创建等。没有关于 ELF 的详细信息,但可以看到两者在哪里匹配。最有用的部分可能是第 1 卷:基本架构的第 3.3 节,以及第 3A 卷:系统编程指南,第 1 部分的第 3 章。

我希望这可以帮助任何深入了解运行 C 程序的内部结构的人,祝你好运。

【讨论】:

    【解决方案2】:

    wikipedia 有一个简短的讨论。

    稍长一点的介绍是here

    here 提供更多详细信息,但我不确定它是否呈现得很好。

    【讨论】:

      【解决方案3】:

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

      所有函数参数都存储在堆栈中,每个函数调用都有不同的堆栈框架,这就是递归函数的工作原理。

      有关更多信息,请参阅this site

      【讨论】:

        【解决方案4】:

        实际上,当你运行任何 C 程序时,它的可执行映像会以一种有组织的方式加载到计算机的 RAM 中,称为进程地址空间或 C 程序的内存布局。

        http://www.firmcodes.com/memory-layout-c-program-2/

        【讨论】:

          【解决方案5】:
          • 所有静态和全局未初始化变量都进入 bss(由 Symbol 启动的块)。
          • 所有初始化的全局/局部/静态变量进一步划分为

          只读

          const int x=10;

          &读/写

          char Str[]="StackOverFlow"

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-11
            • 1970-01-01
            • 2013-05-24
            • 1970-01-01
            • 2016-09-11
            • 1970-01-01
            相关资源
            最近更新 更多