2010-06-01 111 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