2013-04-15 68 views

回答

16

上面的代碼會導致問題。

第一個實例稱爲靜態字符串分配和定義。 對於像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) 

你也應該閱讀了被分割爲現代操作系統的應用程序。這將真正增加您對代碼的構建方式的理解。

參考


  1. 數據段,訪問的2013年4月15日,<http://en.wikipedia.org/wiki/Data_segment>
  2. 代碼段,訪問的2013年4月15日,<http://en.wikipedia.org/wiki/Code_segment>
+2

明白了,謝謝。 – VishalDevgire

+1

我還會添加一個變體:'char str [] =「Stack」'... –

+0

@ValeriAtamaniouk你會是對的。將udpate。謝謝你提醒我。 – DevNull

2

在第一種情況下,您的指針指向在進程內存的只讀部分中分配的const char*
在第二種情況下,您正在動態分配內存,並且事件會將字符串「Stack」複製到您分配的內存中。

您必須最終從II使用free釋放內存。

+0

如果我嘗試寫入只讀區域(第一種情況),會發生什麼情況? – VishalDevgire

+1

你不能,因爲它是'const char *' - 一個常量字符串。你的編譯器會阻止你這樣做。 –

+1

不客氣。首先弄清楚並不容易... –

0

忘記其他答案,聲稱有關存儲內部堆棧的任何內容,因爲它們不正確。(哦,現在這些問題的答案已經被移除。)

case I:你有一個指針str它指向一個只讀存儲區域(.rodata部分),其內容爲"Stack"

case II:你有一個指針str,其指向一個動態分配的區域(在堆),其內容是"Stack",它是可修改和應使用它後invocking free(str)被釋放。

相關問題