我写了空程序,我编译了它。 它分配了12.456个字节的磁盘内存。
然后我添加了静态整数,大小增加了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)
答案 0 :(得分:3)
因为变量的名称存储在二进制文件中以用于调试目的。假设您使用-g
编译,或者如果不进行优化,编译器会自动插入调试符号。如果你用十六进制编辑器查看二进制文件,你可以看到这一点。
这是第一个没有变量的程序的结束。第一列是文件中的十六进制位置。接下来的八个是文件中的十六进制值。最后一列是它的ASCII表示。这是使用完成的。详细信息会有所不同,这是在操作系统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......
这是第三个int1
和char1
。
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
的行为是一样的。