2012-03-29 25 views
4

我有一個非常基本的問題。 讓我們這個片段:C執行堆棧 - 局部變量分配

#include <stdio.h> 

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

int main(void) { 
    foo(); 
} 

在此過程中執行堆棧,主要被加載到堆,然後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一個。我應該看到未初始化的段,如果我做objdump -s -j .data a.out,我應該看到初始化段(abc = 100)rt?這個假設有什麼問題嗎?

我碰到下面的輸出,但:

測試> objdump的-s -j的.bss的a.out 的a.out:文件格式ELF32-I386

測試> objdump的-s -j。數據a.out的

的a.out:文件格式ELF32-I386

部分。數據的內容: 804954c 00000000 3c960408 00000000 6400 .... < ....... d ...

我在這裏錯過了什麼?

感謝大家再次

回答

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)

要在objdump輸出中查看"%s\n"字符串文字,可以使用gcc -fno-builtin編譯程序。

+2

在Linux(及類似系統)上,您可以在二進制文件中使用'objdump -s -j .rodata'來查看它。另外,如果使用'gcc',則不會找到「%s \ n」,因爲'gcc'優化了這個模式以調用'puts()'。 – FatalError 2012-03-29 21:46:12

+0

@FatalError我在與你的評論相同的時間寫了objdump命令:)'puts'的好點我編輯我的答案來添加它。 – ouah 2012-03-29 21:47:41

4

該標準沒有定義"StackOverflow"的存儲位置。

通常,它會存儲在程序的只讀文本部分;有時,它將被存儲在程序的初始化數據部分。這些都不是堆棧;這些都不是'堆'(在由malloc()等管理的動態分配內存的意義上)。格式字符串出現相同的註釋和問題。

+0

感謝大家的好評!真的很感激它! – user999755 2012-03-30 07:45:09

+0

作爲@ ouah和@FatalError建議,通過執行objdump -s -j .rodata a.out,我能夠看到「Stackoverflow」和「%s」。 – user999755 2012-03-30 07:47:25