因此,我繼續瞭解C,並且我有一個有趣的問題。 如果我沒有把錯誤的東西放在堆上,我必須使用malloc
等。 但char * str
呢? 在什麼內存段將str
位於? 我讀過它會放在.bss段(這就是爲什麼你不能在C中改變字符串)。它是否正確?或者將它放在堆棧上?高級C內存分配
如果是的話,爲什麼程序結束時不需要釋放這些內存? 也在每個函數的內存段代碼中?換句話說,指向函數的指針將指向哪個段? 感謝您的幫助! 只是想更好地理解C中的內存管理。
因此,我繼續瞭解C,並且我有一個有趣的問題。 如果我沒有把錯誤的東西放在堆上,我必須使用malloc
等。 但char * str
呢? 在什麼內存段將str
位於? 我讀過它會放在.bss段(這就是爲什麼你不能在C中改變字符串)。它是否正確?或者將它放在堆棧上?高級C內存分配
如果是的話,爲什麼程序結束時不需要釋放這些內存? 也在每個函數的內存段代碼中?換句話說,指向函數的指針將指向哪個段? 感謝您的幫助! 只是想更好地理解C中的內存管理。
如果你把一個定義char *str;
放在一個函數中,那麼它是一個類型爲「pointer-to-char
」的自動變量。
它位於堆棧上,當函數返回時(編譯器通過發送代碼以根據需要移動堆棧指針來處理此堆棧),該堆棧的一部分將變爲未使用。從理論上講,堆棧的存在純粹是一個實現細節,實際上C總是有一個調用堆棧,幾乎所有的實現都或多或少地以相同的方式進行管理,而實際上它是管理的,自動變量存儲的內存是可能被稱爲「堆棧」。
如果你把一個定義char *str;
放在任何函數之外,那麼它是一個具有靜態存儲持續時間的全局變量。
它存儲在一個可讀寫的數據段中,當程序退出時可能未被使用(可能操作系統會爲您處理,儘管它原則上可能是編譯器發出的代碼)。由於它是零初始化的(並且假設所有位爲0的空指針所代表的體系結構)是,它可以進入bss段,這是專門用於具有靜態存儲持續時間的零初始化讀寫對象的。同樣,靜態持續時間對象的存儲細節取決於實現,但再一次,這是它通常完成的方式。
這與字符串文字不可修改有關,因爲您尚未定義字符串(更不用說使用字符串字面量了)。你已經定義了一個指針,它可以指向一個字符串,但是還沒有這樣做。
如果你只是說char * str
數組的內存將不會被分配,只有指針本身的內存。你需要手動分配內存給字符串,可能在堆上,也可能手動釋放它。
「你不能更改C中的字符串」是錯誤的。您不能更改字符串常量,並且字符串常量的分配類似.rodata
(只讀部分)。與其他代碼一樣,函數代碼的位置類似.text
。
在C中,所有局部變量將被放入堆棧。變量str
是一個字符指針。它包含一個內存地址。在堆棧上將只有這個指針str
。
char * str;
這種具有指針(上32/64位4或8個字節)堆棧上的大小分配內存。
str = malloc(1024);
malloc
分配在堆上 1024個字節並返回一個指針,該存儲器區域的第一個字節。該指針保存在位於堆棧上的str
中。
當函數(其中str
是局部變量)返回時,您的變量str
將被釋放。內存區域str
指向的內存區域不會自動釋放。您需要使用free(str)
手動執行此操作。
字符串可以修改!但不是常量字面值:
char string[4] = "foo";
string[0] = 'F'; //will work
char * stringconst = "foo";
stringconst[0] = 'F'; // this will segfault
上述不會工作,因爲「foo」將被放置(只希望)在readonly內存區域。
我認爲你已經混淆了指針和它們指向的內容。藉此:如果多數民衆贊成在文件範圍內聲明的
char *str = "Hello";
,然後str
是靜態分配的指針。它指向的字符串是完全獨立的。你可以有str
指向任何東西。
如果它在函數中聲明,那麼str
是分配在堆棧上的指針。再次,文字是分開的。
事實上,如果你有以下兩行:
char *str1 = "Hello";
char *str2 = "Hello";
的編譯器就可以讓每個指向內存中的同一地址。
無論指針如何,字符串文字都是靜態分配的,並且它(通常)放置在初始化的只讀數據段中。
還要記住,堆棧,堆棧和段的所有概念都與實現完全相關,而不是語言。
我在閱讀類似問題的答案時發現了兩條鏈接。這些可能會幫助你更好地理解這個問題。
在C中,我們可以通過字符數組或字符指針指任一字符串。
情況1:如果字符串被稱爲字符數組:
char[] = "storage of strings";
如果上述聲明是GLOBAL那麼這被存儲在數據段否則這將被存儲在堆棧段。
案例2:如果字符串被字符指針引用,並且在運行時分配內存(即使用malloc,calloc)。
char *str = (char *)malloc(sizeof(char)*size);
在這種情況下,存儲器是從HEAP段中分配的。
案例3:如果通過字符指針引用字符串並將字符串值直接賦值給字符指針。
char *str = "storage of strings"
在這種情況下,這將被存儲在DATA segment.It是像字符串文字被分配在數據段和這個字符串是分配給str變量的地址的存儲器。
PS:每個在運行時分配的內存(HEAP段)都需要在程序本身中釋放。所以如果你使用malloc,calloc或任何在運行時分配內存的函數,你需要使用free()。
也許這可能會幫助http://stackoverflow.com/questions/14004302/how-c-strings-are-allocated-in-memory?rq=1 – 2013-03-22 17:24:04
聲明'char * str;'只分配一個空間指針對象。如果你想指向一個數組(可能包含也可能不包含字符串),那麼必須通過調用'malloc()',通過使用字符串文字,通過定義數組對象或其他東西。 – 2013-03-22 17:25:46
嗨。我的問題是這個內存在哪裏?在堆棧或BSS段? – Farseer 2013-03-22 17:29:03