我正在尝试对方形矩阵的矩阵乘法进行编码,并且在几次试验后每隔几次就会继续给出分段错误。 我在网站上查找了不同的问题,并尝试了以下两个代码。
另外,为什么我们需要指向"指向指针的指针"由int ** mat1,** mat2等给出?我不知道为什么要这样做,但我在某些答案中看到了它。
代码1
void mxmult()
{
int n,m,a,b,c,d, sum=0;
int x,y,z;
printf("Enter first order [n*n]\n");
scanf("%d", &n);
printf("Enter second order [m*m]\n");
scanf("%d", &m);
if (n!=m)
{
printf("Invalid orders");
}
else
{
//mem allocate for matrix 1
int **mat1 = (int**)malloc(n*sizeof(int));
for(x=0;x<n;x++)
{
mat1[x]=(int*)malloc(n*sizeof(int));
}
// input matrix 1
printf("Enter the first matrix entries\n");
for (a = 0; a <n; a++)
{
for (b = 0; b < n; b++)
{
scanf("%d", &mat1[a][b]);
}
}
// memory allocate matrix 2
int **mat2 = (int**)malloc(m*sizeof(int));
for(y=0;y<n;y++)
{
mat2[y]=(int*)malloc(m*sizeof(int));
}
//inpur matrix 2
printf("Enter the second matrix entries\n");
for (c = 0; c <n; c++)
{
for (d= 0; d < n; d++)
{
scanf("%d", &mat2[c][d]);
}
}
//Memory allocate matrix Mult
int **mult=(int**)malloc(m*sizeof(int));
for(z=0;z<m;z++)
mult[z]=(int*)malloc(m*sizeof(int));
for (a = 0; a < n; a++)
{
for (d = 0; d < m; d++)
{
for (c = 0; c < n; c++)
{
sum=sum + (mat1[a][c] *mat2[c][d]);
}
mult[a][d] = sum;
sum= 0;
}
}
printf("Product\n");
for ( a = 0 ; a < n ; a++ )
{
for ( d = 0 ; d < m ; d++)
printf("%d\t", mult[a][d]);
printf("\n");
}
}
}
代码2:
void mxmult()
{
int n,m,a,b,c,d, sum=0;
int x,y,z;
printf("Enter first order [n*n]\n");
scanf("%d", &n);
printf("Enter second order [m*m]\n");
scanf("%d", &m);
if (n!=m)
{
printf("Invalid orders");
}
else
{
//mem allocate for matrix 1
int **mat1 = (int**)malloc(n*n*sizeof(int));
// input matrix 1
printf("Enter the first matrix entries\n");
for (a = 0; a <n; a++)
{
for (b = 0; b < n; b++)
{
scanf("%d", &mat1[a][b]);
}
}
// memory allocate matrix 2
int **mat2 = (int**)malloc(m*m*sizeof(int));
//input matrix 2
printf("Enter the second matrix entries\n");
for (c = 0; c <n; c++)
{
for (d= 0; d < n; d++)
{
scanf("%d", &mat2[c][d]);
}
}
//Memory allocate matrix Mult
int **mult=(int**)malloc(m*m*sizeof(int));
// Mx multiplicatn
for (a = 0; a < n; a++)
{
for (d = 0; d < m; d++)
{
for (c = 0; c < n; c++)
{
sum=sum + (mat1[a][c] *mat2[c][d]);
}
mult[a][d] = sum;
sum= 0;
}
}
printf("Product\n");
for ( a = 0 ; a < n ; a++ )
{
for ( d = 0 ; d < m ; d++)
printf("%d\t", mult[a][d]);
printf("\n");
}
}
}
我一直在尝试执行代码2,然后执行代码2。两人在几次入职后最终都会出现seg故障。
答案 0 :(得分:9)
int **
类型是所谓的不规则数组。你首先分配一个&#34; spine&#34;来创建一个参差不齐的数组。数组,其中包含指向每个&#34; rib&#34;的指针。当您引用matrix[x][y]
时,您在&#34; spine&#34;中取消引用索引x
处的指针,然后将该元素放在索引&#34; y&#34;在&#34; rib&#34;。这是一个很好的图表说明了这个结构:
您可以阅读comp.lang.c FAQ list · Question 6.16: How can I dynamically allocate a multidimensional array?(也是上图中的来源)以获取更多信息。
另一个选择是为矩阵实际分配一个2D数组(我的首选方法)。这需要编译器支持某些C99结构,但除了Microsoft C编译器(例如gcc和clang)之外的所有主要编译器似乎都默认支持这一点。这是一个例子:
int (*matrix)[colCount] = (int(*)[colCount]) malloc(sizeof(int)*rowCount*colCount);
上面的奇怪语法是你declare a pointer to an array in C的方式。需要*matrix
周围的括号来消除它与declaring from an array of pointers的歧义。 You don't need to cast the result of malloc in C,等同于:
int (*matrix)[colCount] = malloc(sizeof(int)*rowCount*colCount);
这为矩阵分配单个内存块,并且由于编译器知道每行的长度(即colCount
),它可以插入数学计算任何2D引用的正确地址。例如,matrix[x][y]
相当于((int*)matrix)[x*colCount+y]
。
我更喜欢分配2D数组,因为你可以在一行中完成所有的分配,而对于不规则的数组,你必须分别设置指向每一行的指针,这通常需要另外几行用于循环。
至于你的段错误,这一行看起来很可疑:
int **mat1 = (int**)malloc(n*sizeof(int));
由于mat1
是int**
类型,mat1
中的每个条目都应为int*
。但是,您的malloc
正在使用sizeof(int)
为条目分配内存!试试这个:
int **mat1 = (int**)malloc(n*sizeof(int*));
假设您使用的是64位系统,sizeof(int)
可能是4(字节),而sizeof(int*)
应该是8(字节)。这意味着您目前正在分配一半的内存,而这需要,这意味着当您访问该数组后半部分的条目时会发生不好的事情。使用正确的大小(sizeof(int*)
)应该解决这个问题。
(可能还有其他问题,但那是乍一看突出的问题。)