【问题标题】:C execution stack - local variable allocationC 执行栈 - 局部变量分配
【发布时间】:2012-03-29 21:41:50
【问题描述】:

我有一个非常基本的问题。 让我们来看看这个sn-p:

#include <stdio.h>

void foo(void) {
    char *s = "StackOverflow";
    printf("%s\n", s);
}

int main(void) {
    foo();
}

在进程执行堆栈中,main 被加载到堆栈中,然后 foo() 被调用。 现在,“StackOverflow”的内存分配在哪里? 同样,调用 printf 时,“%s\n”的内存分配在哪里?


考虑以下代码:

现在我的另一个问题是,考虑以下代码:

#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 .data a.out ,我应该看到初始化段 (abc=100) rt ?这个假设有什么问题吗?

我得到以下输出:

测试> objdump -s -j .bss a.out a.out:文件格式elf32-i386

测试> objdump -s -j .data a.out

a.out:文件格式elf32-i386

.data 部分的内容: 804954c 00000000 3c960408 00000000 64000000 ....<.......d...>

我在这里错过了什么?

再次感谢大家

【问题讨论】:

    标签: c


    【解决方案1】:

    "StackOverflow""%s\n" 字符串文字在大多数系统中都放在 .rodata(只读数据)部分。

    在 UNIX 上,您可以使用 objdump 命令转储 .rodata 部分:

    $ gcc tst.c 
    $ objdump -s -j .rodata a.out
    

    正如 @FatalError 在 cmets 中添加的那样,"%s\n" 在示例中的 objdump 中不可见,因为 gcc 优化了对 printf("%s\n",str) 的调用,将其替换为对 puts(str) 的调用。

    要在 objdump 输出中查看 "%s\n" 字符串文字,您可以使用 gcc -fno-builtin 编译您的程序。

    【讨论】:

    • 在 linux(和类似的)系统上,你可以在你的二进制文件上 objdump -s -j .rodata 来查看它。此外,如果您使用gcc,您将找不到“%s\n”,因为gcc 将该模式优化为对puts() 的调用。
    • @FatalError 我在您发表评论的同时编写了 objdump 命令:) puts 的好点我编辑我的答案以添加它。
    【解决方案2】:

    标准没有定义"StackOverflow" 的存储位置。

    通常,它将存储在程序的只读文本部分中;有时,它会存储在程序的初始化数据部分中。这些都不是堆栈。这些都不是“堆”(在由malloc() 等人管理的动态分配内存的意义上)。格式字符串也会出现相同的 cmets 和问题。

    【讨论】:

    • 正如@ouah 和@FatalError 建议的那样,我可以通过执行 objdump -s -j .rodata a.out 看到“Stackoverflow”和“%s”。
    猜你喜欢
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多