我有一个像这样声明的2D数组:
int arr[2][2]={ {1,2},{3,4}};
现在,如果我这样做:
int ** ptr=(int**) arr;
和
cout<<**ptr;
我遇到了分段错误(使用g ++ - 4.0)。
为什么这样?不应该打印值1(等于arr[0][0]
)?
答案 0 :(得分:5)
您不能将线性数组转换为指向指针的类型,因为int**
不能保存相同的数据int[][]
。
第一个包含指向指针的指针。第二个包含一系列整数,在线性记忆中。
答案 1 :(得分:2)
您现在所做的就是创建指针数组,其中每个指针都是 显式转换 。因此,您将拥有像(0x00001, 0x00002, 0x00003 and 0x00004
)这样的指针数组。
取消引用时,此指针会导致您的段错误。
答案 2 :(得分:1)
不,int **
是指向int的指针,但是2-D数组是数组数组,而&(arr[0][0])
是指向int的指针。
我相信你应该这样做:
int *ptr = arr;
cout<<*ptr;
或者这个:
int *ptr = &arr[0][0];
cout<<*ptr;
答案 3 :(得分:1)
您正在尝试将双指针变量分配给数组...这已经详尽地介绍了,有关此信息,请参阅here。此外,因为你声明了
int arr[2][2] = ...;
然后尝试将arr
分配给双指针
int ** ptr = ... ;
保证不起作用,因此出现分段错误。此外,该语句int ** ptr=(int**) arr;
实际上是 强制 一种类型(即[] [])到另一种类型(即**),尽管它们属于' INT”。它们都不同,编译器会以非常不同的方式解释......
你可以这样做:
int *ptr = &arr;
现在*(ptr + 1)
将引用第0行,*(ptr + 2)
将引用第1行,依此类推。你唯一的责任是不要超越使用arr
的标记,否则可能发生溢出甚至是分段错误......
答案 4 :(得分:0)
尝试
int *ptr = arr;
更多说明:
您应该为指针指定一个地址,因此可以对其进行解除(我的意思是*运算符)。你所做的是,将ptr指向具有地址a [0] [0]的存储单元。因此,您会遇到分段错误。
答案 5 :(得分:0)
int arr[2][2]
不是数组数组 - 它是一个单独的2d数组。在内存中,它与int arr[4]
你真正想要的是
int (*ptr)[2] = arr;