簡體   English   中英

C中的字符串參數是否動態分配?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM