静态字符分配更多磁盘内存然后静态整数

时间:2017-01-18 00:56:29

标签: c static allocation

我写了空程序,我编译了它。 它分配了12.456个字节的磁盘内存。

enter image description here

然后我添加了静态整数,大小增加了32个字节(大小现在是12.488个字节)。但是当我添加静态char时,大小增加了40个字节。为什么static char分配的磁盘内存多于static int?

编辑:

我在x86_64机器上运行GNU Compiler。 这是来源,

int
main(void) {

}

分配:12456 B磁盘存储器。

int
main(void) {
    static int int1;
}

分配:12488字节(+32 B)

int
main(void) {
    static int int1;
    static char char1;
}

分配:12528字节(+40 B)

1 个答案:

答案 0 :(得分:3)

因为变量的名称存储在二进制文件中以用于调试目的。假设您使用-g编译,或者如果不进行优化,编译器会自动插入调试符号。如果你用十六进制编辑器查看二进制文件,你可以看到这一点。

这是第一个没有变量的程序的结束。第一列是文件中的十六进制位置。接下来的八个是文件中的十六进制值。最后一列是它的ASCII表示。这是使用enter image description here完成的。详细信息会有所不同,这是在操作系统X上clang -g

000010e0: 0000 0000 0000 0000 2000 5f5f 6d68 5f65  ........ .__mh_e
000010f0: 7865 6375 7465 5f68 6561 6465 7200 5f6d  xecute_header._m
00001100: 6169 6e00 6479 6c64 5f73 7475 625f 6269  ain.dyld_stub_bi
00001110: 6e64 6572 002f 5573 6572 732f 7363 6877  nder./Users/schw
00001120: 6572 6e2f 746d 702f 0074 6573 742e 6300  ern/tmp/.test.c.
00001130: 2f76 6172 2f66 6f6c 6465 7273 2f30 622f  /var/folders/0b/
00001140: 3778 7032 6c78 6264 3779 6c30 7463 706d  7xp2lxbd7yl0tcpm
00001150: 7330 3666 7233 6434 3030 3030 676e 2f54  s06fr3d40000gn/T
00001160: 2f74 6573 742d 6439 6332 6233 2e6f 005f  /test-d9c2b3.o._
00001170: 6d61 696e 0000 0000                      main....

这是仅有int1的第二个。

00002100: 0000 0000 0000 0000 2000 5f5f 6d68 5f65  ........ .__mh_e
00002110: 7865 6375 7465 5f68 6561 6465 7200 5f6d  xecute_header._m
00002120: 6169 6e00 6479 6c64 5f73 7475 625f 6269  ain.dyld_stub_bi
00002130: 6e64 6572 002f 5573 6572 732f 7363 6877  nder./Users/schw
00002140: 6572 6e2f 746d 702f 0074 6573 742e 6300  ern/tmp/.test.c.
00002150: 2f76 6172 2f66 6f6c 6465 7273 2f30 622f  /var/folders/0b/
00002160: 3778 7032 6c78 6264 3779 6c30 7463 706d  7xp2lxbd7yl0tcpm
00002170: 7330 3666 7233 6434 3030 3030 676e 2f54  s06fr3d40000gn/T
00002180: 2f74 6573 742d 3136 6564 3035 2e6f 005f  /test-16ed05.o._
00002190: 6d61 696e 005f 6d61 696e 2e69 6e74 3100  main._main.int1.
000021a0: 5f6d 6169 6e2e 696e 7431 0000 0000 0000  _main.int1......

这是第三个int1char1

00002120: 0000 0000 0000 0000 2000 5f5f 6d68 5f65  ........ .__mh_e
00002130: 7865 6375 7465 5f68 6561 6465 7200 5f6d  xecute_header._m
00002140: 6169 6e00 6479 6c64 5f73 7475 625f 6269  ain.dyld_stub_bi
00002150: 6e64 6572 002f 5573 6572 732f 7363 6877  nder./Users/schw
00002160: 6572 6e2f 746d 702f 0074 6573 742e 6300  ern/tmp/.test.c.
00002170: 2f76 6172 2f66 6f6c 6465 7273 2f30 622f  /var/folders/0b/
00002180: 3778 7032 6c78 6264 3779 6c30 7463 706d  7xp2lxbd7yl0tcpm
00002190: 7330 3666 7233 6434 3030 3030 676e 2f54  s06fr3d40000gn/T
000021a0: 2f74 6573 742d 3036 3865 3366 2e6f 005f  /test-068e3f.o._
000021b0: 6d61 696e 005f 6d61 696e 2e69 6e74 3100  main._main.int1.
000021c0: 5f6d 6169 6e2e 6368 6172 3100 5f6d 6169  _main.char1._mai
000021d0: 6e2e 696e 7431 005f 6d61 696e 2e63 6861  n.int1._main.cha
000021e0: 7231 0000 0000 0000                      r1......

如果没有-g且根本没有优化标记,我会得到一个相似但不那么罗嗦的结果。

00002080: 0000 0000 0000 0000 2000 5f5f 6d68 5f65  ........ .__mh_e
00002090: 7865 6375 7465 5f68 6561 6465 7200 5f6d  xecute_header._m
000020a0: 6169 6e00 6479 6c64 5f73 7475 625f 6269  ain.dyld_stub_bi
000020b0: 6e64 6572 005f 6d61 696e 2e69 6e74 3100  nder._main.int1.
000020c0: 5f6d 6169 6e2e 6368 6172 3100 0000 0000  _main.char1.....

如果我在没有-g-O的情况下编译进行优化,那么就不会有符号,因为编译器不会为调试保留变量名,也因为优化器会删除未使用的变量。

00001060: 0000 0000 0000 0000 2000 5f5f 6d68 5f65  ........ .__mh_e
00001070: 7865 6375 7465 5f68 6561 6465 7200 5f6d  xecute_header._m
00001080: 6169 6e00 6479 6c64 5f73 7475 625f 6269  ain.dyld_stub_bi
00001090: 6e64 6572 0000 0000                      nder....

所有三个程序都是等效的,并使用clang -O生成完全相同的二进制文件。我认为gcc的行为是一样的。