这是我执行的简单代码
int a;
int main()
{
return 0;
}
然后用gcc编译后我做了
size a.out
我在bss和数据部分得到了一些输出......然后我将我的代码改为
int a;
int main()
{
char *p = "hello";
return 0;
}
再次当我在编译后通过大小a.out看到输出时,数据部分的大小保持不变。但是我们知道字符串hello将在只读初始化部分中分配内存。那么为什么数据部分的大小保持不变?
答案 0 :(得分:5)
#include <stdio.h>
int main()
{
return 0;
}
它给出了
text data bss dec hex filename
960 248 8 1216 4c0 a.out
当你做
时int a;
int main()
{
char *p = "hello";
return 0;
}
它给出了
text data bss dec hex filename
982 248 8 1238 4d6 a.out
当时hello存储在.rodata
中,并且该地址的位置存储在char指针p
中,但此处p存储在堆栈中
和size不显示堆栈。我不确定但.rodata在这里以文本或十进制计算。
当你写
int a;
char *p = "hello";
int main()
{
return 0;
}
它给出了
text data bss dec hex filename
966 252 8 1226 4ca a.out
现在这里再次“hello”存储在.rodata中,但char指针占用4个字节并存储在数据中,因此数据增加4个
了解更多信息http://codingfreak.blogspot.in/2012/03/memory-layout-of-c-program-part-2.html
答案 1 :(得分:2)
实际上,这是一个实现细节。编译器按原样工作。这意味着只要程序的行为相同,就可以自由地排除它想要的任何代码。在这种情况下,它可以完全跳过char* p = "hello"
。
答案 2 :(得分:2)
字符串“hello”在.rodata
答案 3 :(得分:1)
即使总大小没有改变,也不代表代码没有改变。
我测试了你的例子。
字符串“hello”是一个常量数据,因此它存储在readonly .rodata部分中。
您可以使用objdump查看此特定部分,例如:
objdump -s -j .rodata <yourbinary>
使用gcc 4.6.1没有任何选项,我得到了你的第二个代码:
Contents of section .rodata:
4005b8 01000200 68656c6c 6f00 ....hello.
答案 4 :(得分:0)
由于您未在代码中使用char *
,因此编译器对其进行了优化。