[英]Are string arguments in C dynamically allocated?
假設我有一個具有以下規范的函數:
void example(char* str)
如果我傳入一個字符串參數,例如:
example("testing");
“測試”的值是否在堆上動態分配,因此在能夠調用“示例”的函數的范圍被破壞(並且需要稍后釋放)之后,我將能夠使用它,或者它是否是本地的堆棧上的變量,所以我需要使用malloc創建一個新的字符串,並將值存儲在那里,如果我希望它繼續存在,比如一個hashmap?
謝謝。
當您在程序中編寫"testing"
時,它將被編譯為字符串文字,並且在編譯期間將分配它的空間。 當你得到一個指向它的指針時,它是指向內存中該位置的指針。 你不需要用malloc()
來分配它,你也不應該free()
它。 但是嘗試修改其內容也不是一個好主意,因為編譯器可能會將它放在只讀區域(也就是說,它被編譯為常量) - 例如,以下程序在我的Linux桌面上崩潰:
#include <stdio.h>
int main() {
char *a = "abc\n";
a[0]='X';
printf(a);
return(0);
}
在C中,引號之間的字符串“this this”被稱為字符串文字 。
字符串文字,例如您在上面給出的內容,不會動態分配。 通常,它們在編譯和/或鏈接時分配,並且可以在只讀存儲器中分配。 (這就是為什么,在C ++中,字符串文字是const char
而不是char
。)
在引擎蓋下,一些編譯器在字符串表中隱藏“測試”,生成一個特殊的指針。 它大致相當於:
char *const compiler_generated_pointer_to_testing = (char *) (compiler_generated_string_table + 12345);
...
const char compiler_generated_string_table[] = {
...
't', 'e', 's', 't', 'i', 'n', 'g', 0,
...
};
...
example( compiler_generated_pointer_to_testing );
這是它可以發揮作用的一種方式。 許多其他實現都是合法的。 無論如何,實現細節可能除此之外。 要記住的真正要點是:
const
,即使編譯器不要求您將指針聲明為const char *
。 foo("testing")
和bar("testing")
)不能保證是不同的指針,也不能保證它們是相同的指針值。 free()
一個字符串文字。 得到了那一切? 任何問題?
最常見的是,它將作為字符串文字存儲在可執行文件的只讀部分中。 您實際上可以通過使用-S
標志編譯程序來手動驗證。
它將生成一個名為name_of_your_app.s
的程序集可執行文件,您可以在其中找到字符串文字(它將位於所謂的數據段中 )。
有時,編譯器可以放入代碼段,或者根據優化級別,它將簡單地優化它(最容易通過創建一個未在任何地方使用的字符串文字來檢查,然后在GCC上使用-O3
標志進行編譯)。
這是一個(人為的)例子:
int main()
{
char *a = "Hai!";
return 0;
}
如果我編譯它沒有特殊標志,字符串文字仍然存在:
$ gcc -S main.c
main.c: In function ‘main’:
main.c:9:11: warning: unused variable ‘a’ [-Wunused-variable]
$ cat main.s | grep Hai
.string "Hai!"
但是,一旦我提高了優化級別,就不再是這樣了:
$ gcc -S -O3 main.c
main.c: In function ‘main’:
main.c:9:11: warning: unused variable ‘a’ [-Wunused-variable]
$ cat main.s | grep Hai
$
看起來這個答案解決了同樣的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.