首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C(64位)中的内存分配布局问题

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

Stack Overflow用户
提问于 2019-02-20 06:45:28
回答 2查看 314关注 0票数 1

我想了解"C“程序是如何运行的,并将数据存储在机器中。因此,我查看了来自这里的C的内存布局,并在我的机器中遵循了相同的指令,即64位。

首先,当我编写程序(main只有return 0;)并对可执行文件使用size命令时:它在文本段和数据段上显示了很大的差异。

代码语言:javascript
复制
text    data    bss     dec     hex     filename
10648   2400    2640    15688   3d48    33.exe

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

代码语言:javascript
复制
text    data    bss     dec     hex     filename
960     248     8       1216    4c0     memory-layout

第一个问题:负责内存分配的因素(硬件/软件)是什么?布局中的dec所指的是什么?/问题在这里结束

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

对于此代码:

代码语言:javascript
复制
#include <stdio.h> 
int global;  
int main(void) {
    //static int x;
    return 0; 
} 

我得到的输出如下:

代码语言:javascript
复制
text    data    bss     dec     hex     filename
10648   2400    2656    15704   3d48    33.exe

这是因为我声明(未初始化)一个全局变量,这就是为什么将16字节(int-64位)的内存块添加到bss中,因此它从2640 (第一个示例)变为2656,我理解这一点。

Q2:但是当我添加static int x时,它不再向bss添加内存块了。这是意料之中吗?

代码语言:javascript
复制
text    data    bss     dec     hex     filename
10648   2400    2656    15704   3d48    33.exe 

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

代码语言:javascript
复制
text    data    bss     dec     hex     filename
10648   2416    2656    15720   3d48    33.exe

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

( Arigato:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-20 07:34:33

负责内存分配的因素(硬件/软件)是什么?布局中的dec指的是什么?

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

但是,当我添加静态int时,它不是将内存块添加到bss anymore.is中,而是它期望的内存块吗?

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

在添加静态变量之前:

代码语言:javascript
复制
   text    data     bss     dec     hex filename
   1099     544       8    1651     673 a.out

添加静态变量后:

代码语言:javascript
复制
   text    data     bss     dec     hex filename
   1099     544      16    1659     67b a.out

最后,当我用20初始化全局变量时,数据会增加(预期),而dec也会增加。为什么?

因为dectextdatabss之和

票数 1
EN

Stack Overflow用户

发布于 2019-02-20 08:01:16

以下是一个简短的总结:

  • 可执行代码、字符串文本和常量全局变量被加载到文本段中,在支持它的系统上,OS程序加载程序在内存中进行只读操作。
  • 全局初始化可修改对象和用static存储声明的本地初始化对象被加载到数据段中。
  • 未初始化的可修改的全局对象和未初始化的本地static对象分配到bss段中,可执行文件中不存在这些对象。
  • 其他具有自动存储的本地对象是动态地从堆栈段中分割出来的,当它们进入作用域时,这些对象有时会动态地输入函数。
  • dec列给出程序代码和数据的总大小:文本databss之和。这不包括启动时分配的内存、堆栈空间,也不包括从堆或使用其他OS特定方法动态分配的数据。
  • 十六进制dec的十六进制表示。

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

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

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

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

现代操作系统处理更多关于可执行程序的片段和复杂性,上面的方法是一种简单的方法,它在1970年代和1980年代对早期Unix系统中可执行程序的内存布局进行建模。这些名字比Unix早了近20年。可以使用objdumpnm实用程序显示更多信息。

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

文本细分市场

data细分市场

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54780355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档