首页 > 解决方案 > 更改符号后,我的代码停止工作

问题描述

我对指针和数组非常陌生。我将不胜感激任何帮助。

我正在尝试编写矩阵乘法代码。起初我的代码看起来像这样:

#include <stdio.h>
#include <stdlib.h>

void populate (int inp_row,int inp_col,int *arr);
void multiplication(int *arr1,int *arr2,int *arr3,int inp_row,int inp_col);
void display(int *arr,int inp_row,int inp_col);

int main(){
    srand(time(NULL));

    int row,col;

    printf("Enter number of rows: ");
    scanf("%d",&row);

    printf("Enter number of columns: ");
    scanf("%d",&col);

    int*arrA=(int *)malloc(row*col*sizeof(int));
    int*arrB=(int *)malloc(row*col*sizeof(int));
    int*arrC=(int *)malloc(row*col*sizeof(int));

    populate(row,col,arrA);
    populate(row,col,arrB);

    multiplication(arrA,arrB,arrC,row,col);

    printf("Your Matrices are as follows:\n=============================");
    printf("\nMatrix A is as follows:\n");
    display(arrA,row,col);
    printf("\nMatrix B is as follows:\n");
    display(arrB,row,col);
    printf("\nResults:\n=============================");
    printf("\nA * B is as follows:\n");
    display(arrC,row,col);
}

void populate (int inp_row,int inp_col,int *arr){
    int i,j;

    for(i=0;i<inp_row;i++)
        for(j=0;j<inp_col;j++)
            *(arr + inp_row*i + j)=rand()%11;
}

void multiplication(int *arr1,int *arr2,int *arr3,int inp_row,int inp_col){
    int i,j,k;

    for(i=0;i<inp_row;i++)
        for(j=0;j<inp_col;j++)
            *(arr3 + inp_row*i + j)=0;

    for(i=0;i<inp_row;i++)
        for(j=0;j<inp_col;j++)
            for(k=0;k<inp_col;k++)
                *(arr3 + inp_row*i + j)=(*(arr1 + inp_row*i +k)*(*(arr2 + inp_row*k + j))+*(arr3 + inp_row*i + j));
}

void display(int *arr,int inp_row,int inp_col){
    int i,k;

    for(i=0;i<inp_row;i++){
        printf("\n|");printf("%d",*(arr + inp_row*i + 0));
        for(k=0;k<(inp_col-1);k++)
            printf("  %d",*(arr + inp_row*i + k));
        printf("|");
    }
}

打印似乎很好,它并没有停止工作。唯一的问题看起来像是数学。乘法给出了错误的答案。我查看了一些在线资源,我认为我的算法看起来不错。然后我基本上开始搞乱代码..

我查看了我的讲义并更改了数组符号并添加了内存分配错误消息。

现在代码在要求输入后停止工作,我似乎无法理解。

我对这种动态数组表示法也很陌生。通常我像以前的代码一样编写它们。这可能是问题所在。

#include <stdio.h>
#include <stdlib.h>

void populate (int inp_row,int inp_col,int **arr);
void multiplication(int **arr1,int **arr2,int **arr3,int inp_row,int inp_col);
void display(int **arr,int inp_row,int inp_col);

int main(){
    srand(time(NULL));

    int row,col;

    printf("Enter number of rows: ");
    scanf("%d",&row);

    printf("Enter number of columns: ");
    scanf("%d",&col);

    int**arrA=(int **)malloc(row*sizeof(int));
    int**arrB=(int **)malloc(row*sizeof(int));
    int**arrC=(int **)malloc(row*sizeof(int));

    if(arrA == NULL || arrB == NULL|| arrC == NULL){
        printf("\nCouldn't allocate the memmory!");
        return -1;}

    int i;
    for(i=0;i<col;i++){
        arrA[i]=(int*)malloc(sizeof(int)*col);
        arrB[i]=(int*)malloc(sizeof(int)*col);
        arrC[i]=(int*)malloc(sizeof(int)*col);
        if(arrA[i] == NULL || arrB[i] == NULL|| arrC[i] == NULL){
            printf("\nCouldn't allocate the memmory!");
            return -2;}}

    populate(row,col,arrA);
    populate(row,col,arrB);

    multiplication(arrA,arrB,arrC,row,col);

    printf("Your Matrices are as follows:\n=============================");
    printf("\nMatrix A is as follows:\n");
    display(arrA,row,col);
    printf("\nMatrix B is as follows:\n");
    display(arrB,row,col);
    printf("\nResults:\n=============================");
    printf("\nA * B is as follows:\n");
    display(arrC,row,col);
}

void populate (int inp_row,int inp_col,int **arr){
    int i,j;

    for(i=0;i<inp_row;i++)
        for(j=0;j<inp_col;j++)
            arr[i][j]=rand()%11;
}

void multiplication(int **arr1,int **arr2,int **arr3,int inp_row,int inp_col){
    int i,j,k,sum=0;

    for(i=0;i<inp_row;i++)
        for(j=0;j<inp_col;j++)
            arr3[i][j]=0;

    for(i=0;i<inp_row;i++)
        for(j=0;j<inp_col;j++)
            for(k=0;k<inp_col;k++){
                sum+=arr1[i][k]*arr2[k][j];}
    arr3[i][j]=sum;
}

void display(int **arr,int inp_row,int inp_col){
    int i,k;

    for(i=0;i<inp_row;i++){
        printf("\n|");printf("%d",arr[i][0]);
        for(k=0;k<(inp_col-1);k++)
            printf("  %d",arr[i][k]);
        printf("|");
    }
}

标签: carrayspointers

解决方案


如果你在 下运行gdb,你的程序会multiplication一个循环中出现段错误。

那是因为你的第一批malloc来电main不正确。

改变:

int **arrA = (int **) malloc(row * sizeof(int));
int **arrB = (int **) malloc(row * sizeof(int));
int **arrC = (int **) malloc(row * sizeof(int));

进入:

int **arrA = (int **) malloc(row * sizeof(int *));
int **arrB = (int **) malloc(row * sizeof(int *));
int **arrC = (int **) malloc(row * sizeof(int *));

Anint是 32 位,但 [显然] 你在 64 位机器上,所以指针是 64 位。因此,您没有为指针分配足够的空间。

这是未定义的行为,可能需要一些时间才能导致故障。我的猜测是该populate调用破坏了内存,但并没有杀死自己。但是,它留下的是multiplication试图取消引用的无效指针值。


如果使用 编译,则会标记-Wall -O2以下行:multiplication

arr3[i][j] = sum;

和:

warning: ‘j’ may be used uninitialized in this function [-Wmaybe-uninitialized]

正如 MrBens 所提到的,这条线可能应该进入循环内部


但是,数学对我来说仍然不正确。我对矩阵乘法有点生疏,但我在维基百科上查了一下[而且我喝咖啡,所以...]

我认为你应该sum在循环内归零。

所以,我会改变这个:

for (i = 0; i < inp_row; i++) {
    for (j = 0; j < inp_col; j++) {
        for (k = 0; k < inp_col; k++) {
            sum += arr1[i][k] * arr2[k][j];
        }
    }
}
arr3[i][j] = sum;

进入:

for (i = 0; i < inp_row; i++) {
    for (j = 0; j < inp_col; j++) {
        sum = 0;
        for (k = 0; k < inp_col; k++)
            sum += arr1[i][k] * arr2[k][j];
        arr3[i][j] = sum;
    }
}

推荐阅读