2013-04-23 86 views
2

我想將一維數組指針和二維數組指針放入聯合中,這樣我就可以以任何方式訪問數據。在下面的程序中,我希望看到值9通過兩種方式打印出來。如何在聯合中使用指針

#include <iostream> 
class A { 
public: 
    union { 
     int** array2D; 
     int* array1D; 
    }; 
    A() { 
     array2D = new int*[1]; 
     array2D[0] = new int[1]; 
    } 
}; 

int main() { 
    A a; 
    a.array2D[0][0] = 9; 
    cout << a.array2D[0][0] << endl; 
    cout << a.array1D[0] << endl; 
    cout << a.array2D << endl; 
    cout << a.array1D << endl; 
} 

實際輸出:

9 
146989080 
0x8c2e008 //Pointer address of array2D 
0x8c2e008 //Pointer address of array1D 

的地址是相同的,並且通過定義多維數組存儲在相同的方式,是一維陣列。我不知道爲什麼兩個cout打印出不同的結果?我錯過了什麼?

編輯: 感謝以下答案,我可以看到我錯過了什麼。 用於從array1D訪問數據修復的方法是:

cout << *((int*) a.array1D[0]) << endl;

+2

如果您不知道這一點,您的'array1D'就'持'指向'array2D'第一行的指針。 – WhozCraig 2013-04-23 06:13:19

+0

@WhozCraig是的我沒有意識到這一點:D 我認爲使用'new'定位數組與聲明一個固定大小的數組是一樣的,這就是誤導了我。 – 2013-04-23 06:28:00

回答

4

首先要調用未定義行爲的。

的標準說,你只能從你上次寫T,閱讀array2Darray1D互換,因此是不允許工會的會員才能閱讀(即使它在實踐中經常工作,首先推薦) 。

秒;使用array1D您試圖取消引用並讀取當前地址處的值(據推測,因爲UB)已被分配爲new int*[1],因此array2D[0][0]的值位於路徑的另一步。


要訪問您從a.array1D期待當你打印出來的a.array2D值時,您將需要的東西,如下面的(不推薦)

**reinterpret_cast<int**> (a.array1D); 
+0

謝謝,'reinterpret_cast'對我來說是新的。我用'*((int *)a.array1D [0]',它工作正常,我希望它可以安全使用,即使我不知道爲什麼不推薦。 – 2013-04-23 06:29:57

2

當您分配使用new多維數組,就做到這一點時,實際上是分配數量的陣列。 第一個是指向數組的指針數組。因此,您的a.array1D[0]實際上包含指向數組指針的指針,並且您正在打印指針的值。

我敢肯定,如果你做到以下幾點:

cout << (int*)a.array1D[0] << endl; 

你會得到相同的:

cout << a.array2D[0] << endl; 
+0

當你爲'new'分配一個多維數組時,你正在分配一個連續的塊:'int(* ar)[10] = new int [10] [10];'。它本質上不是一個指針數組。 OP的代碼*是一個指針數組,除了使用的語法外,它不是任何方式的多維數組。 – WhozCraig 2013-04-23 06:16:46

+0

@WhozCraig固定。 – Alex 2013-04-23 06:18:30

+0

+1這實際上是使用模擬多維數組時如何佈置指針數組的更好的描述之一(並且不要太羅嗦,也不要太誇張),並且就如何與OP的問題有關。 – WhozCraig 2013-04-23 06:31:05

2

值是指向數組的開始。由於您使用的是聯合,因此array1Darray2D佔用相同的空間並將包含相同的值。

當您訪問a.array1D[0]中的指針值時,您告訴它獲取第一個元素array1D。因爲您正在使用union,這也指向array2D的第一個元素,它恰好是一個指針。