全局变量如何影响可执行文件的大小?

时间:2010-12-04 08:36:27

标签: c size vxworks

是否有全局变量会增加可执行文件的大小?如果有,怎么样?它是仅增加数据部分大小还是文本部分大小?

如果我有一个全局变量和初始化如下:

char g_glbarr[1024] = {"jhgdasdghaKJSDGksgJKASDGHKDGAJKsdghkajdgaDGKAjdghaJKSDGHAjksdghJKDG"};

现在,这是否将1024添加到数据部分,并将启动字符串的大小添加到文本部分?

如果相反,如果静态地为这个数组分配空间,如果我对它进行malloc,然后执行memcpy,那么只会减少数据部分的大小,或者文本部分的大小也会减少?

4 个答案:

答案 0 :(得分:5)

是的,确实如此。基本上编译器将它们存储到数据段。有时如果在代码中使用常量char数组(如printf("<1024 char array goes here");),它将转到数据段(AFAIK一些旧的编译器/ Borland?/可能将它存储在文本段中)。您可以强制编译器将全局变量放在自定义部分中(对于VC ++,它是#pragma data_seg(<segment name>))。

动态内存分配不会影响数据/文本段,因为它会在堆中分配内存。

答案 1 :(得分:3)

答案是依赖于实现的,但对于理智的实现,这就是它对具有静态存储持续时间(全局或其他)的变量的工作方式:

  • 每当初始化变量时,对象的整个初始化值将存储在可执行文件中。即使只显式初始化它(其余部分隐含为零),也是如此。
  • 如果变量是常量并且已初始化,则它将位于“文本”段中,或等效。有些系统(现代基于ELF,也许是Windows?)对于只读数据有一个单独的“rodata”段,允许它被标记为不可执行,与程序代码分开。
  • 非常量初始化变量将位于可执行文件的“数据”段中,当程序加载时,操作系统会以写时复制模式将其映射到内存中。
  • 未初始化的变量(根据标准隐式为零)将不会在可执行文件本身中保留存储空间,而是“bss”段中的大小和偏移量,该段由操作系统在程序加载时创建。
  • 这些未初始化的变量可以在一个单独的只读“bss”类段中创建,如果它们是const - 合格。

答案 2 :(得分:2)

我不是作为专家发言,但我猜想只是在程序中使用史诗般的字符串文字会增加可执行文件的大小。你使用该字符串文字做什么并不重要,因为它必须存储在某处

为什么可执行文件的哪个“部分”增加了?这不是一个修辞问题!

答案 3 :(得分:1)

答案略微实施敏感,但总的来说,没有。您的g_glbarr实际上是指向char或地址的指针。字符串本身将以常量字符串放入数据部分,g_glbarr将在编译时成为字符串地址的符号。您最终不会为指针分配空间,编译器只需在链接时解析地址。

<强>更新

@Jay,它有点相同。整数(通常)只是在线:编译器将尽可能接近将常量放在代码中,因为这是一种常见的情况,大多数普通架构都有直接的方法从即时数据中完成。字符串常量仍将在某些只读数据部分中。所以当你做出类似的东西时:

// warning: I haven't compiled this and wouldn't normally
// do it quite this way so I'm not positive this is
// completely grammatical C
struct X {int a; char * b; } x = { 1, "Hello" } ; 

1成为“立即”数据,"Hello"在某处只读数据中分配,编译器只生成一些分配读写数据的东西

x:
x.a:   WORD    1
x.b    WORD    @STR42

其中STR42是内存中字符串"Hello"位置的符号名称。然后,当所有内容链接在一起时,@STR42将替换为内存中字符串的实际虚拟地址。