2010-06-01 66 views
8

可能重複:
casting char[][] to char** causes segfault?INT ** VS INT [ROWS] [COLS]

我有一個2D陣列聲明如下:

int arr[2][2]={ {1,2},{3,4}}; 

現在,如果我這樣做:

int ** ptr=(int**) arr; 

和:

cout<<**ptr; 

我得到一個分段錯誤(使用G ++ - 4.0)。

爲什麼這麼說?它不應該打印值1(等於arr[0][0])?

+3

我認爲這是C++中的重要原則:「如果你要投,你不能買得起它的」 http:/ /blogs.msdn.com/b/oldnewthing/archive/2009/10/23/9911891.aspx – SergGr 2010-06-01 16:51:02

回答

1

您正在嘗試將一個雙指針變量賦值給一個數組......這已經被詳盡地討論過,詳情請參見here。此外,由於你宣佈

 
int arr[2][2] = ...; 

,然後嘗試分配arr的雙指針

 
int ** ptr = ... ; 

這是保證不工作,因此分段錯誤。此外,該聲明int ** ptr=(int**) arr;實際上荷蘭國際集團的一種類型(即[] [])爲另一種類型(即**)儘管它們是類型的「INT」。他們都是不同的編譯器會解釋的是非常不同的...

你可以這樣來做:

 
int *ptr = &arr; 

現在*(ptr + 1)將引用第0行,*(ptr + 2)將指1 'st row等等。你唯一的責任是不超過arr使用的標記,否則會發生溢出甚至是分段錯誤...

0

嘗試

int *ptr = arr; 

更多的解釋:

不應該將ADRESS分配給指針,因此它可以derefenced(我的意思是*運算)。你所做的是,將ptr指向具有地址a [0] [0]的存儲單元。因此,您會遇到分段錯誤。

5

由於int**不保存相同的數據int[][],所以不能將線性陣列轉換爲指針指針類型。 第一個保存指針到指針的指針。第二種是線性存儲器中的一系列整數。

+0

那麼,你可以像OP那樣。你只需要做一個reinterpret_cast,OP不知道該做什麼,因爲他們正在使用C風格的演員。就像所有這樣的轉換當然,訪問新指針的結果是UB。 OP應該得到的道德是:使用C++進行C++轉換。 – 2010-06-01 17:06:18

1

不,int **是一個指向int的指針,但是二維數組是一個數組的數組,而&(arr[0][0])是一個指向int的指針。

我相信你應該這樣做:

int *ptr = arr; 
cout<<*ptr; 

或本:

int *ptr = &arr[0][0]; 
cout<<*ptr; 
2

你做什麼現在意味着指針數組的創建,每一個指針是明確鑄造。因此,您將擁有一組指針,如(0x00001, 0x00002, 0x00003 and 0x00004)。

當取消引用時,這個指針會導致你的段錯誤。

0

int arr[2][2]不是陣列數組 - 它是一個單獨的二維數組。在內存方面,它無法區分int arr[4]

你真正想要的是

int (*ptr)[2] = arr; 
+0

形式上,它*是一個數組數組。但是,是的,由於數組是連續佈局的,並且不允許填充,所以'int [2] [2]'的確按照內存中的int [4]'佈局。 – caf 2010-06-02 05:04:44