2015-11-04 89 views
-2
..... 
// Some code 
char *options[] = {"\nDATA:","\nSUBJECT:","\nMAILFROM:","\nRCPTO:"}; 
char *data[3] = {}; 

我正在初始化這個指針數組。爲什麼兩個指針都顯示相同的內存地址

但是,當我嘗試訪問指針的陣列的每個成員,我可以看到, 選項[0] =數據[3] 0x40873b = 0x40873b 它們都指向同一個存儲單元。

即使我在'data'數組之前聲明瞭'options'數組。 那麼如何解決這個問題。 如何確保它們位於不同的內存位置並正確存儲內容。不重疊,不同的數據位於不同的位置。

+9

'data [3]'超出界限。數組只有索引0,1和2. – user694733

+0

即使這個程序沒有包含所提到的未定義的行爲錯誤,仍然可能最終有兩個指針指向相同的位置,因爲這些指針指向_constant字符串文字_無法修改。如果程序中有兩個這樣的文字,它們都是「hello」,然後用一個唯一的指針指向每個文字,那麼這兩個文字仍然可以分配在相同的內存地址,因爲編譯器可以告訴它們是相同並且它們是隻讀的。這是一個稱爲「字符串池」的編譯器優化。 – Lundin

回答

1

當編寫

char *data[3] = {}; 

[3]的裝置「爲陣列的三個元素分配空間」。 這並不意味着你已經創建了一個名爲 data[3]指針(其實data[3]是不是一個指針) 也不是data[3]是爲 剛剛分配的內存的一部分;而是,分配用於 陣列的存儲器的三個元素是data[0],,和data[2], ,其在所述存儲器位置data(0x408738), data + 1(0x408739)和data + 2(0x40873a)。

如果你寫

data[3] == options[0] 

然後data[3]意味着無論是在存儲位置data + 3, 這是的data最後分配的元素之後的第一件事。 編譯器碰巧已經在那裏爲options啓動了內存分配 ,也就是說,位置0x40873b是options的第一個內容被找到的地方。

1

看起來像奠定你的對象,編譯器列如下:

  +---+ 
    data: | | data[0] 
      +---+ 
      | | data[1] 
      +---+ 
      | | data[2] <-- last element of data array 
      +---+ 
options: | | options[0], data[3] 
      +---+ 
      | | options[1], data[4] 
      +---+ 
      | | options[2], data[5] 
      +---+ 
      | | options[3], data[6] <-- last element of options array 
      +---+ 

data數組包含3個元素,索引爲0到2,當您訪問data[3],你所訪問的對象一個在data陣列的末尾,成爲options陣列的第一個對象。

請注意,嘗試讀取超過數組末尾的對象會調用未定義的行爲; C沒有對數組訪問進行任何邊界檢查,所以這樣做不會引發OutOfBounds異常或類似的情況。在這種情況下,由於data數組的最後一個元素後面的對象與該元素的類型相同(char *),因此您獲得了合理的值。理論上,您可以使用data(如上所示)遍歷整個options數組,儘管在這個特定情況下這隻會「有效」;如果您添加另一個變量或更改代碼,編譯器可能會更改內存中事物的排列順序,並且這會突然不再「工作」。

+0

上面所說的一切都被理解了。但是這個問題的解決方案稱爲「字符串池」? – user1421147

+0

@ user1421147:Lundin描述的「字符串池」不是問題;可以讓多個指針指向相同的字符串文字,因爲字符串文字應該是不可變的。但是,如果你想擁有同一個字符串的多個副本,你需要爲每個副本分配內存,例如'char * copy = malloc(strlen(str)+ 1);如果(複製)strcpy(copy,str);' –

+0

我想要的是我的字符串數據不應該重疊。我希望數據[3]和選項[0]存儲不同的數據,而不是指向同一個內存位置。我可以控制哪些內存位置可以存儲哪些數據? – user1421147

相關問題