我正在使用Code:Block。
编译以下代码(无错误)并在运行时出现分段错误。
void print(int size, int **a)
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";/**Segmentation fault here**/
}
cout<<endl;
}
}
int main()
{
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int size = sizeof(a)/sizeof(a[0]);
print(size,(int **)a);
return 0;
}
我尝试使用不同的传递数组的方法:
void print(int size, int a[][4])
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int size = sizeof(a)/sizeof(a[0]);
print(size,a);
return 0;
}
我没有错误,代码成功运行。
对于第一个代码,而不是使用a[i][j]
,我尝试使用*(*(a+i)+j)
,得到了分段错误。
然后我在分段错误点调试了第一个代码并吸收了以下内容:
> p a
$1 = (int **) 0x22fd30
> p *a
$2 = (int *) 0x200000001
> p **a
Cannot access memory at address 0x200000001
我相信a
拥有2d数组的第一个地址。但是对于p ** a,错误消息中显示了不同的地址。
然后我在http://ideone.com/中运行了第一个代码并遇到了运行时错误。我哪里弄错了?为什么调试器显示不同的地址?。
答案 0 :(得分:1)
在你的第一个例子中
void print(int size, int **a)
期望类型为的第二个参数指向指向int 的指针。但是这里
int a[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
print(size,(int **)a);
传递一个变量类型 4个4个数组的数组。当您将数组传递给function时,数组会衰减到指向其第一个元素的指针。实际上,函数print
得到类型为int *[4]
的参数 - 指向4个整数的数组的指针,这不是print
所期望的。这是一个错误。您从编译器隐藏此错误,告诉他a
类型为int **
。它没有。因此分割错误。
在你的第二个例子中
void print(int size, int a[][4])
需要一个类型 4个整数数组的参数。当它传递给int *[4]
函数时,它会衰减到a
,这恰好是print
的类型。这里没有错误。
答案 1 :(得分:0)
如果索引int **,例如在[0]中,结果类型为int *。如果再次索引,如在[0] [0]中,它将解释第一个元素(是整数1)(或64位的前两个元素)作为指向int(int *)的指针并尝试取消引用它,这显然是不正确的,通常会导致分段错误。
你的C风格演员表(int **)被翻译成reinterpret_cast。这就是为什么我不喜欢C风格的演员表,因为他们所做的并不总是很明显。
简而言之:使用你的转换为(int **),你告诉编译器它是一个指向int的指针数组,它不是:它是一个int [4]&#39;的数组。
编辑:我对64位的评论仅适用于sizeof(int)始终为4的平台。我相信linux sizeof(int)== sizeof(int *)。
答案 2 :(得分:0)
将cout<<a[i][j]<<" ";
替换为cout<<a[i*size+j]<<" ";
答案 3 :(得分:0)
您遇到的问题是因为两者的数据类型不同。 int arr [] []与int ** arr不同。当你声明int arr []时让我们从1-d数组看,arr和int * arr一样。当你试图在内部访问arr [i]编译器做什么*(arr + i)。但是当你声明 int arr [] [size]时,arr的数据类型是int(* arr)[size] ,这与int ** arr不同。这就是你得到错误的原因。请参阅此Link
答案 4 :(得分:0)
以下适用于我:
分配和分配:
int** foo( int N, int M)
{
int** arr;
arr = (int **)malloc(sizeof(int *)*N);
for(int i=0; i < N; i++) {
arr[i] = (int *)malloc(sizeof(int)*M);
}
int x=0;
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
arr[i][j]=x;
x++;
}
}
return arr;
}
现在您可以像这样使用它:
void print(int size, int a[][4])
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
int N=2;
int M=3;
int** foo = bar(N,M);
print(arr,N,M);
}