2010-08-07 29 views
2

假設我有一個數組(本地功能)和一個指針字符串初始化和只讀部分

char a[]="aesdf"char *b="asdf"

我的問題是在前者的情況下字符串文字"aesdf"存儲在只讀部分,然後被複制到本地陣列或者是類似於

char a[]={'a','e','s','d','f','\0'};

我認爲在這種情況下,字符是直接在堆棧上創建的,但在較早的情況下(char a[]="aesdf"),字符從只讀部分複製到本地數組。

威爾`「aesdf」存在可執行文件的整個生命?

+0

與此問題非常相似:http://stackoverflow.com/questions/3427750/difference-between-array-initializations – eldarerathis 2010-08-07 04:01:46

回答

0

a [] =「aesdf」和char a [] = {'a','e','s','d','f','\ 0'}將被存儲在函數的run時間堆棧和內存將在函數返回時釋放。但對於char * b =「asdf」,asdf存儲在readonly部分中,並從那裏引用。

0
char a[] = "aesdf"; 
char a[] = {'a','e','s','d','f','\0'}; 

這兩行代碼具有相同的效果。編譯器可以選擇以相同的方式實現它們,也可以選擇以不同的方式實現它們。

從在C程序員編寫代碼的角度來看,應該不是真正的問題。您可以使用任何一種方法,並確保您將最終得到一個初始化爲指定內容的六元素數組char

"aesdf"存在的可執行文件的整個生命?

語義上說,是的。字符串文字是char數組有靜態存儲時間。具有靜態存儲持續時間的對象具有程序執行的生命週期:它在程序啓動之前被初始化,並且一直存在,直到程序終止。

但是,這在你的程序中根本不重要。該字符串文字用於初始化數組a。既然你沒有獲得一個指向字符串本身的指針,那麼它的實際生命週期是什麼也沒有關係,或者它是如何實際存儲的。只要數組a被正確初始化,編譯器就可以做它認爲合適的事情。

5

從視抽象和正式點,每個字符串文字是具有靜態存儲持續時間的獨立無名對象。這意味着,在初始化char a[] = "aesdf"正式創建文字對象"aesdf",然後使用它來初始化獨立陣列a,即,它是不等同於char *a = "aesdf",其中指針被製成指向直接字符串文字。

然而,由於字符串文字無名對象,在char a[] = "aesdf"變種有沒有辦法之前或初始化之後訪問獨立"aesdf"對象。這意味着你無法「檢測」這個對象是否真的存在。該對象的存在(或不存在)不會影響程序的可觀察行爲。由於這個原因,該實現具有消除獨立對象的所有自由,並以任何其他方式初始化該陣列,從而導致預期的正確結果,即作爲char a[] = { 'a', 'e', 's', 'd', 'f', '\0' }char a[] = { 'a', 'e', "sdf" }或作爲別的東西。

2

第一:

char a[]="aesdf"; 

假設這是一個自動局部變量,將分配在堆棧上的6個字節,並與給定的字符初始化它們。它是如何執行的(無論是通過字符串文字中的memcpy還是使用內聯存儲指令一次加載一個字節,或者其他方式)都完全由實現定義。請注意,每次變量進入範圍時都必須進行初始化,所以如果它不會改變,這是一個非常浪費的構造。

如果這是一個靜態/全局變量,它將生成一個具有唯一地址/存儲的6字節char數組,其初始內容是給定字符,並且是可寫的。

下一頁:

char *b="asdf"; 

這將初始化指針b指向一個字符串"asdf",這可能會或可能不會與其他字符串文字共享存儲,並且如果你寫它產生不確定的行爲。

+0

是否真的,第二個語句'char * b =「asdf」;'是保存在只讀 - 只有記憶?因爲,當我嘗試執行'* b ='A';'時,gcc編譯器上的行爲就是分段錯誤。 – chao 2014-05-07 15:52:39

+1

'b'不是「保存在只讀存儲器」,因爲你可以修改它(指向別的東西)。你已經將它初始化爲指向一個不能被修改的字符串文字(試圖修改它來調用未定義的行爲),所以編譯器可以自由地將它放在只讀存儲器中,但不是必需的。 – 2014-05-07 22:33:59