尝试访问二维数组时发生SIGSEGV错误

时间:2018-11-06 16:41:56

标签: c

我想在r * r矩阵上做一个简单的转置函数。在下面的代码中,当我到达temp = mat [i] [j]行时,我得到了SIGSEGV。 但我真的不明白为什么。任何提示将不胜感激。

void transpose(int** mat, size_t col)
{
 int i = 0;
 int j = 0 ;

 for(i= 0; i< col; ++i)
 {
    for(j = i ; j< col; ++j)
    {
        int temp = mat[i][j];
        mat[i][j] = mat[j][i];
        mat[j][i] = temp;
    }
 }
}
void printMat(int* arr, int size)
{
 int i = 0;
 for(i = 0 ; i< size*size ;++i)
 {
    printf("%d| ", arr[i]);
    if((1+i)%size == 0)
    {
        printf("\n");
    }
 }
}
int main()
{
 int arr[][3] = {{1,2,3},{4,5,6},{7,8,9}};
 printMat((int*)arr, 3);
 transpose((int**)arr, 3);
 printMat((int*)arr, 3);

return 0;
}

3 个答案:

答案 0 :(得分:1)

void transpose(int ** mat,size_t col)表示您有一个指向指针数组的指针。

但是数组只是一块内存

将void transpose(int ** mat,size_t col)更改为

void transpose(int mat[][3], size_t col)

可以工作

答案 1 :(得分:1)

如果您使用的是int数组的本机数组,则不能强制将其强制馈送到需要一个指向一系列指针的函数。所有这些强制转换都清楚地表明您正在做错事。谁告诉你int[N][M]int**的代名词;他们不是。

大多数工具链供应商都在C中的自动变量位置(包括函数参数)中支持VLA(可变长度数组)。唯一的要求是大小必须在参数列表中的数组之前:

#include <stdio.h>

void transpose(size_t siz, int mat[][siz])
{
    for(size_t i= 0; i< siz; ++i)
    {
        for(size_t j = i ; j< siz; ++j)
        {
            int temp = mat[i][j];
            mat[i][j] = mat[j][i];
            mat[j][i] = temp;
        }
    }
}

void printMat(size_t siz, int const arr[][siz])
{
    for(size_t i=0; i<siz; ++i)
    {
        for (size_t j=0; j<siz; ++j)
            printf("%d| ", arr[i][j]);
        fputc('\n',stdout);
    }
}

int main()
{
    int arr[][3] = {{1,2,3},{4,5,6},{7,8,9}};
    printMat(3, arr);
    transpose(3, arr);
    printMat(3,arr);

    return 0;
}

输出

1| 2| 3| 
4| 5| 6| 
7| 8| 9| 
1| 4| 7| 
2| 5| 8| 
3| 6| 9| 

See it live

答案 2 :(得分:0)

所以,我在考虑如何在内存中设置2D数组,需要使用col来让编译器知道在行之间跳过多少个int(在这种情况下),但是实际上2D数组是只需将其设置为内存中的常规数组,即连续的内存块即可。

所以-如果我想在行之间“移动”,我自己可以简单地计算出偏移量。例如,如果我要求编译器将mat视为普通的int数组,则在mat [col_num * 1 +0]中设置元素mat [1,0]。

我想以此方式设置函数的原因是,我希望该函数可以运行而不必#define col 3或将其设置为函数定义的原义int(int mat [] [3])。记住我在main中声明的int mat [] [3]在调用函数时必须转换为(int *)mat,这有效:

void TransposeOfD2Array(int* mat, size_t col)
{
    int i = 0;
    int j = 0;

   for(i= 0; i< col; ++i)
   {
     for(j = i ; j< col; ++j)
     {
     int temp = mat[(col*i)+j];
       mat[(col*i)+j] = mat[(col*j)+i];
       mat[(col*j)+i] = temp;
     }
   }
}
void printMat(int* arr, int size)
{
  int i = 0;
  for(i = 0 ; i< size*size ;++i)
  {
     printf("%d| ", arr[i]);
     if((1+i)%size == 0)
     {
         printf("\n");
     }
  }
}
int main()
{
   int mat[][3] = {{0,1,2},{3,4,5},{6,7,8}};
   TransposeOfD2Array((int*)mat, 3);
   printMat((int*)mat, 3);
   return 0;
}