I. char *str = "Stack";
II. char *str = (char*) malloc(6);
strcpy(str, "Stack");
上述兩種方法之間有什麼區別?聲明字符串和分配字符串之間的區別
窗簾背後它們是否相同或不同?
I. char *str = "Stack";
II. char *str = (char*) malloc(6);
strcpy(str, "Stack");
上述兩種方法之間有什麼區別?聲明字符串和分配字符串之間的區別
窗簾背後它們是否相同或不同?
上面的代碼會導致問題。
第一個實例稱爲靜態字符串分配和定義。 對於像int
等常規變量和非字符串數據類型,這樣的聲明會在堆棧上分配數據。在字符串通過字符串文字初始化的情況下(即:"stack"
),它被分配在內存的只讀部分。
字符串本身不應該被修改,因爲它將被存儲在內存的只讀部分。指針本身可以更改爲指向新的位置。
即:
char strGlobal[10] = "Global";
int main(void) {
char* str = "Stack";
char* st2 = "NewStack";
str = str2; // OK
strcpy(str, str2); // Will crash
}
爲了安全起見,你應該實際分配作爲一個指針,指向常量數據,即:
const char* str = "Stack"; // Same effect as char* str, but the compiler
// now provides additional warnings against doing something dangerous
第二被稱爲動態分配,其中在分配內存堆,而不是堆棧。該字符串可以修改而不麻煩。在某些情況下,您需要通過free()
命令釋放這個動態分配的內存。
第三種方法是分配一個字符串,它是堆棧上的靜態分配。這允許您修改保存該字符串的數組的內容,並且它是靜態分配的。
char str[] = "Stack";
總結:如何數據
Example: Allocation Type: Read/Write: Storage Location:
================================================================================
const char* str = "Stack"; Static Read-only Code segment
char* str = "Stack"; Static Read-only Code segment
char* str = malloc(...); Dynamic Read-write Heap
char str[] = "Stack"; Static Read-write Stack
char strGlobal[10] = "Global"; Static Read-write Data Segment (R/W)
你也應該閱讀了被分割爲現代操作系統的應用程序。這將真正增加您對代碼的構建方式的理解。
參考
<http://en.wikipedia.org/wiki/Data_segment>
<http://en.wikipedia.org/wiki/Code_segment>
在第一種情況下,您的指針指向在進程內存的只讀部分中分配的const char*
。
在第二種情況下,您正在動態分配內存,並且事件會將字符串「Stack」複製到您分配的內存中。
您必須最終從II使用free
釋放內存。
如果我嘗試寫入只讀區域(第一種情況),會發生什麼情況? – VishalDevgire
你不能,因爲它是'const char *' - 一個常量字符串。你的編譯器會阻止你這樣做。 –
不客氣。首先弄清楚並不容易... –
忘記其他答案,聲稱有關存儲內部堆棧的任何內容,因爲它們不正確。(哦,現在這些問題的答案已經被移除。)
case I:
你有一個指針str
它指向一個只讀存儲區域(.rodata
部分),其內容爲"Stack"
。
case II:
你有一個指針str
,其指向一個動態分配的區域(在堆),其內容是"Stack"
,它是可修改和應使用它後invocking free(str)
被釋放。
明白了,謝謝。 – VishalDevgire
我還會添加一個變體:'char str [] =「Stack」'... –
@ValeriAtamaniouk你會是對的。將udpate。謝謝你提醒我。 – DevNull