C(64 位)中的内存分配布局问题

Memory allocation layout issues in C (64-bit)

我想了解 "C" 程序如何运行并将数据存储在机器中。 因此,我从 here 查看了 C 的内存布局,并在我的 64 位机器中遵循了相同的说明。

首先我写程序的时候(main只有return 0;),对可执行文件使用了size命令:在文本和数据上都表现出很大的差异段。

text    data    bss     dec     hex     filename
10648   2400    2640    15688   3d48    33.exe

但是在上面提到的网站中显示:

text    data    bss     dec     hex     filename
960     248     8       1216    4c0     memory-layout

第一个问题: 负责内存分配的因素(hardware/software)是什么? 布局中的 dec 指的是什么? /问题到此结束

但首先我忽略了这一点并开始声明变量(全局和静态)以查看它们的存储位置。我在这个阶段遇到了问题。

对于此代码:

#include <stdio.h> 
int global;  
int main(void) {
    //static int x;
    return 0; 
} 

我得到的输出为:

text    data    bss     dec     hex     filename
10648   2400    2656    15704   3d48    33.exe

那是因为我声明(未初始化)一个全局变量,这就是为什么 16 字节(int-64 位)的内存块被添加到 bss 所以它从 2640 变成了 2656(第一个例子)我明白了。

Q2:但是当我添加 static int x 时,它不再将内存块添加到 bss。这是预期的吗?

text    data    bss     dec     hex     filename
10648   2400    2656    15704   3d48    33.exe 

Q3:最后当我用 20 初始化全局变量时,data 增加了(预期)并且 dec 也增加了为什么增加了?

text    data    bss     dec     hex     filename
10648   2416    2656    15720   3d48    33.exe

我知道我在这里问了很多问题,但我想确切地知道这种内存管理在 C 中是如何工作的。

阿里加托:)

What are the factors (Hardware/Software) that are responsible for the memory allocation?. And what does dec in the layout refer to

你的程序在运行时分成了很多段。 stack 包含局部变量。 bss data 包含 未初始化的 全局变量。 initialized data 包含初始化的全局变量。 text 包含您的文本(代码)。 dectextbssdata

的总和

But when i add the static int x it is not adding the memory block to bss anymore.is it expected?

保持它未初始化然后它会添加。

添加静态变量前:

   text    data     bss     dec     hex filename
   1099     544       8    1651     673 a.out

添加静态变量后:

   text    data     bss     dec     hex filename
   1099     544      16    1659     67b a.out

And finally when i initialize the global variable with 20, data got incremented (expected) and dec also got incremented. Why?

因为dectextdatabss

的总和

这里是一个简短的总结:

  • 可执行代码、字符串文字和常量全局变量被加载到 text 段,[=101= 在内存中将其设置为只读] 支持它的系统上的程序加载器。

  • 全局初始化的可修改对象和用static存储声明的局部初始化对象加载到数据段。

  • 未初始化的可修改全局对象和未初始化的局部static对象分配在bss段中,可执行文件中不存在。

  • 其他具有自动存储功能的本地对象是在函数输入时从 堆栈 段动态雕刻的,有时当它们进入作用域时会在运行中。

  • dec列给出了程序代码和数据的总大小:text,databss。这不包括在启动时分配的内存、堆栈 space,也不包括从堆或使用其他 OS 特定方法动态分配的数据。

  • hexdec的十六进制表示。

这些值因操作系统、编译器、编译器设置和库而异。该网站显示系统 运行 CentOS 上的输出,可能处于 32 位模式。请注意同一程序如何为所有段生成更大的值,这主要是由于不同的 C 库启动代码。 main 函数本身应该使用几个字节到最多几十个字节,具体取决于编译选项。

可执行文件的大小与 dec 不同,因为它不包含 bss 数据,但包含有关如何执行的其他信息加载程序:各个段的大小和位置、对动态库的引用和来自它们的 link 的符号、调试信息等

添加全局变量时,未初始化的bss增加,否则data增加。添加局部变量时,如果它是静态的,也会发生同样的情况。

但请注意,对齐问题可能会影响数据添加到段的方式,优化设置可能会影响新对象是否实际添加到可执行文件中。如果编译器可以确定一个对象从未被使用过,它可能会完全忽略它。

现代操作系统处理更多关于可执行程序的段和复杂性,以上是一种简单的方法,它模拟了 1970 年代和 80 年代早期 Unix 系统中可执行程序的内存布局。这些名称早于 Unix 将近 2 年。可以使用 objdumpnm 实用程序显示更多信息。

您可以在此处阅读有关标准 Unix 段名称的详细说明:

文本: https://en.wikipedia.org/wiki/Code_segment

数据: https://en.wikipedia.org/wiki/Data_segment

bss: https://en.wikipedia.org/wiki/.bss