我有一个非常基本的问题。 让我们看看这个片段:
#include <stdio.h>
void foo(void) {
char *s = "StackOverflow";
printf("%s\n", s);
}
int main(void) {
foo();
}
在进程执行堆栈中,main被加载到堆栈,然后调用foo()。 现在,分配了“StackOverflow”的内存在哪里? 类似地,当调用printf时分配给“%s \ n”的memroy是什么?
请考虑以下代码:
现在我的另一个问题是,考虑下面的代码:
#include <stdio.h>
int x;
int abc = 100;
void foo(void) {
char *s = "stackoverflow";
printf("%s\n", s);
}
int main(void) {
foo();
}
所以,如果我做objdump的-s -j的.bss a.out的,我应该看到未初始化的段,如果我做objdump的-s -j。数据的a.out,我应该看到初始化段(ABC = 100)室温?这个假设有什么问题吗?
我得到以下输出:
测试&gt; objdump -s -j .bss a.out a.out:文件格式elf32-i386
测试&gt; objdump -s -j .data a.out
a.out:文件格式elf32-i386
部分内容.data: 804954c 00000000 3c960408 00000000 64000000 ....&lt; ....... d ...
我在这里缺少什么?
再次感谢大家
答案 0 :(得分:6)
"StackOverflow"
和"%s\n"
字符串文字放在.rodata
(只读数据)部分。
在UNIX上,您可以使用objdump命令转储.rodata
部分:
$ gcc tst.c
$ objdump -s -j .rodata a.out
由@FatalError在评论中添加,"%s\n"
在示例中与objdump不可见,因为gcc
通过调用printf("%s\n",str)
来优化对puts(str)
的调用"%s\n"
。
要在objdump输出中查看gcc -fno-builtin
字符串文字,可以使用{{1}}编译程序。
答案 1 :(得分:4)
标准没有定义"StackOverflow"
的存储位置。
通常,它将存储在程序的只读文本部分中;有时,它将存储在程序的初始化数据部分中。这些都不是堆栈;这些都不是'堆'(在malloc()
等人管理的动态分配内存的意义上)。格式字符串也会出现相同的注释和问题。