5

这是我执行的一个简单代码

int a;
int main()
{
    return 0;
}

然后在用 gcc 编译后我做了

size a.out

我在 bss 和数据部分得到了一些输出......然后我把我的代码改成了这个

int a;
int main()
{
    char *p = "hello";
    return 0;
}

再次,当我在编译后看到大小为 a.out 的输出时,数据段的大小保持不变..但是我们知道字符串 hello 将在只读初始化部分分配内存..那么为什么数据段的大小保持不变?

4

5 回答 5

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 存储在堆栈中

并且大小不显示堆栈。我不确定,但 .rodata 在这里以文本或 dec 计算。


当你写

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

于 2012-09-27T08:15:25.843 回答
2

实际上,这是一个实现细节。编译器按原样工作。这意味着只要程序的行为相同,就可以自由地排除它想要的任何代码。在这种情况下,它可以完全跳过char* p = "hello"

于 2012-09-27T07:53:01.497 回答
2

字符串“hello”分配在section中.rodata

于 2012-09-27T07:53:23.437 回答
1

即使总大小没有改变,也不意味着代码没有改变。

我测试了你的例子。字符串“hello”是一个常量数据,因此它存储在只读的 .rodata 部分中。您可以使用 objdump 查看此特定部分,例如:
objdump -s -j .rodata <yourbinary>

使用没有任何选项的 gcc 4.6.1,我得到了您的第二个代码:

Contents of section .rodata:
 4005b8 01000200 68656c6c 6f00               ....hello.
于 2012-09-27T08:14:23.123 回答
0

由于您没有char *在代码中使用它,因此编译器对其进行了优化。

于 2012-09-27T07:53:41.793 回答