【问题标题】:C- whats the problem with this code? I try to multiply one matrix in another matrix in func and get new matrix but i get segmentation faultC-这段代码有什么问题?我尝试在 func 中将一个矩阵与另一个矩阵相乘并得到新矩阵,但出现分段错误
【发布时间】:2018-12-11 17:14:39
【问题描述】:

这是我正在开发的程序。任务是乘以 2 个矩阵。矩阵 A 中的列数与矩阵 B 中的行数相同。我让用户可以选择插入两个矩阵包含的内容。 这是我的代码:

#include <stdio.h>
void multiplyMat(int n,int p,int c,int m,int d,int q,int k,int **multiply, 
int **first,int **second);
int main()
{
  int m, n, p, q, c, d, k;
  int first[10][10], second[10][10], multiply[10][10];

  printf("Enter number of rows and columns of first matrix\n");
  scanf("%d%d", &m, &n);
  printf("Enter elements of first matrix\n");

  for (c = 0; c < m; c++)
    for (d = 0; d < n; d++)
      scanf("%d", &first[c][d]);

  printf("Enter number of rows and columns of second matrix\n");
  scanf("%d%d", &p, &q);

  printf("Enter elements of second matrix\n");

  for (c = 0; c < p; c++)
     for (d = 0; d < q; d++)
        scanf("%d", &second[c][d]);

multiplyMat(n,p,c,m,d,q,k,multiply,first,second);
printf("Product of the matrices:\n");

for (c = 0; c < m; c++) {
  for (d = 0; d < q; d++)
    printf("%d\t", multiply[c][d]);
printf("\n");
}
return 0;
}

void multiplyMat(int n,int p,int c,int m,int d,int q,int k,int **multiply, 
int **first,int **second){
    int sum=0;
    if (n == p){
        for (c = 0; c < m; c++) {
           for (d = 0; d < q; d++) {
                for (k = 0; k < p; k++) {
                    sum = sum + first[c][k]*second[k][d];
                }

            multiply[c][d] = sum;
            sum = 0;
            }
        }
    }
    else
        printf("The matrices can't be multiplied with each other.\n");

}

我得到“分段错误”。 它发生在代码进入“sum = sum + first[c][k]*second[k][d]”时 我做了什么导致它? 可能是因为我使用了错误的指针定义。

【问题讨论】:

  • int **multiply 与您的 first[10][10] 不同。当您打开警告时,您的编译器会告诉您什么?
  • @PaulOgilvie:他可能需要更多的解释。
  • 搜索 [c] segmentation fault passing 2D array 会产生 plethora 这个问题的重复项。你这样做了吗?
  • 指针first/second/multiply衰减到的类型不是int**,而是int(*)[10],即。 e.指向长度为 10 的数组的指针,所以完全不同...
  • 要了解实际数组和指向int **first等指针的指针之间的区别,这个问题和答案高度相关:Correctly allocating multi-dimensional arrays

标签: c


【解决方案1】:

int **multiply 是“指向 int 指针的指针”,也被解释为“指向 int 指针数组的指针”。

所以int **multiplyint *multiply[]是相同的,你可以使用i= multiply[1][3];编译器将取消引用multiply,添加1个指针的大小,然后取消引用该元素并添加3个整数的大小,然后得到该 int 并将其分配给 i

但是你传递了一个二维数组。二维数组不是包含指向行的指针的列数组。它只是一块内存,在其中你有列乘以一行,一个接一个地整齐地排列。

现在你创建一个函数来做乘法。但是该函数不知道一行有多少列。因此编译器无法将multiply[1][2] 评估为multiply[10][10] 第二行的第三个元素。

要实现您想要的,有三种可能性:

  1. 在行大小的函数中声明具有大小的矩阵,例如multiply[][10]。这允许编译器在你的函数中进行地址计算(你仍然必须告诉它有多少行)

  2. 使用现代编译器,您可以动态指定数组大小:

    f(int rows, int cols, int a[rows][cols])
    
  3. 自己计算地址。 (我不会选择这个选项;我希望你有一个现代编译器)。

【讨论】:

  • 我不明白。我通过了“int **multiply”,为什么它不好?
  • 我使用选项编号 2。当我将数字放入“f(int rows, int cols, int a[rows][cols])” 时:f(int rows, int cols, int a[10][10]) 它的工作很好,但是当我使用变量时,我会在结果中得到奇怪的数字。
  • 为了完整性:对于函数参数,int a[rows][cols] 等价于int a[][cols] 等价于int (*a)[cols],即。 e. outermost 维度始终只是一个指针!只要rows 参数设置正确,int a[somethingTotalltDifferent][cols] 仍然可以。但是,这不适用于其他维度(即 int(*)[10]int(*)[12]不同的类型)。
  • @shaykeshok,变量必须是尺寸的size,而不是使用了多少元素。例如,您的m, n 被询问用户并且是正在使用的元素的数量,但它们必须是10, 10,因为这些是维度的大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
相关资源
最近更新 更多