显示错误值:C 指针或 malloc 问题?

问题描述 投票:0回答:1

我的程序将矩阵 1 与矩阵 2 相乘。矩阵 3 就是结果。 我可以使用正确的值显示矩阵 1 和矩阵 2,但无法通过相同的函数显示矩阵 3 的预期值,尽管计算值很好。

这是我可以编译的代码。

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

struct Dimensions {
    int dim1, dim2;
};

struct Dimensions enterDimensions(void);

int **createMatrix(int, int);

void deleteMatrix(int **);

void displayMatrix(int **, int, int);

int **multiply(int **, int **, int, int, int);

int main(void) {
    struct Dimensions dimensions1 = enterDimensions();
    int **matrix1 = createMatrix(dimensions1.dim1, dimensions1.dim2);
    displayMatrix(matrix1, dimensions1.dim1, dimensions1.dim2);
    struct Dimensions dimensions2 = enterDimensions();
    int **matrix2 = createMatrix(dimensions2.dim1, dimensions2.dim2);;
    displayMatrix(matrix2, dimensions2.dim1, dimensions2.dim2);

    if (dimensions1.dim2 != dimensions2.dim1) {
        printf("the product of these matrixes does not exist");
    } else {
        int **matrix3 = multiply(matrix1, matrix2, dimensions1.dim1, dimensions1.dim2, dimensions2.dim2);
        displayMatrix(matrix3, dimensions1.dim1, dimensions2.dim2);
        deleteMatrix(matrix3);
    }

    deleteMatrix(matrix1);
    deleteMatrix(matrix2);

    return 0;
}

struct Dimensions enterDimensions(void) {
    int dim1;
    int dim2;
    struct Dimensions dimensions;
    printf("dim 1 : \n");
    scanf("%d", &dim1);
    printf("dim 2 : \n");
    scanf("%d", &dim2);
    dimensions.dim1 = dim1;
    dimensions.dim2 = dim2;

    return dimensions;
}

int **createMatrix(int dim1, int dim2) {
    printf("%s", "\ncreate matrix\n");
    int **matrix = malloc(dim1 * sizeof(int *));
    for (int i = 0; i < dim1; i++) {
        matrix[i] = malloc(dim2 * sizeof(int));
    }

    for (int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            printf("enter (%d,%d)\n", i, j);
            scanf("%d", &matrix[i][j]);
            printf("%d\n", matrix[i][j]);
        }
    }

    return matrix;
}

void deleteMatrix(int **matrix) {
    printf("%s", "\ndelete matrix\n");
    free(matrix); // /!\ Warning : Parameter 'matrix' may point to deallocated memory when called from function 'main'
}    

void displayMatrix(int **matrix, int dim1, int dim2) {
    if (matrix == NULL) {
        exit(1);
    }
    for (int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            if (j == dim2 - 1) {
                printf("[%d]\n", matrix[i][j]);
            } else {
                printf("[%d]", matrix[i][j]);
            }
        }
    }
}

int **multiply(int **matrix1, int **matrix2, int dim11, int dim12, int dim22) {
    int **matrix3 = malloc(dim11 * sizeof(int));
    for (int i = 0; i < dim11; i++) {
        for (int j = 0; j < dim22; j++) {
            int cij = 0;
            for (int k = 0; k < dim12; k++) {
                if (matrix1 == NULL || matrix2 == NULL) {
                    exit(3);
                }
                cij += matrix1[i][k] * matrix2[k][j];
            }

            for (int l = 0; l < dim11; l++) {
                matrix3[l] = malloc(dim22 * sizeof(int));
            }
            matrix3[i][j] = cij;
            printf("cij : %d\n", matrix3[i][j]);
        }
    }
    return matrix3;
};

这里有一个输出:

dim 1 :
2
dim 2 :
2

create matrix
enter (0,0)
1
1
enter (0,1)
0
0
enter (1,0)
0
0
enter (1,1)
1
1
[1][0]
[0][1]
dim 1 :
2
dim 2 :
2

create matrix
enter (0,0)
3
3
enter (0,1)
3
3
enter (1,0)
3
3
enter (1,1)
3
3
[3][3]
[3][3]
cij : 3
cij : 3
cij : 3
cij : 3
[-253143104][428]
[-253143104][3]

delete matrix

delete matrix

delete matrix

Process finished with exit code 0

[-253143104][428]
[-253143104][3]

这是错误的结果。 在你看来,问题是什么? 非常感谢。

PS:如果您有一些改进我的代码的想法,请随时告诉我,因为我是初学者。

PS2:如下所述,我忘记了第一个 malloc 乘法中 int 的 * 。但我改正后仍然有问题。

c pointers matrix malloc
1个回答
0
投票

存在多个问题:

  • deleteMatrix
    仅释放行指针数组。 您应该传递行数 (
    dim1
    ),以便释放保存矩阵值的各个行。

  • displayMatrix
    应该简化:你应该在内循环结束时无条件输出换行符。

  • enterDimensions
    createMatrix
    应检测并报告输入错误和分配失败。

  • multiplyMatrix
    未正确分配结果矩阵:为每个结果单元格值分配多次其行。 最终结果是大量内存泄漏,并且只有每行的最后一个值在最终结果矩阵中显示正确。

这是修改后的版本:

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

struct Dimensions {
    int dim1, dim2;
};

struct Dimensions enterDimensions(void);
int **allocateMatrix(int rows, int cols);
int **createMatrix(int rows, int cols);
void deleteMatrix(int **mat, int rows);
void displayMatrix(int **mat, int rows, int cols);
int **multiply(int **mat1, int **mat2, int dim11, int dim12, int dim22);

int main(void) {
    struct Dimensions dimensions1 = enterDimensions();
    int **matrix1 = createMatrix(dimensions1.dim1, dimensions1.dim2);
    printf("matrix1:\n");
    displayMatrix(matrix1, dimensions1.dim1, dimensions1.dim2);

    struct Dimensions dimensions2 = enterDimensions();
    int **matrix2 = createMatrix(dimensions2.dim1, dimensions2.dim2);;
    printf("matrix2:\n");
    displayMatrix(matrix2, dimensions2.dim1, dimensions2.dim2);

    if (dimensions1.dim2 != dimensions2.dim1) {
        printf("cannot compute the product of these matrices: dimensions do not match\n");
        deleteMatrix(matrix1, dimensions1.dim1);
        deleteMatrix(matrix2, dimensions2.dim1);
        return 1;
    } else {
        int **matrix3 = multiply(matrix1, matrix2, dimensions1.dim1, dimensions1.dim2, dimensions2.dim2);
        printf("matrix3:\n");
        displayMatrix(matrix3, dimensions1.dim1, dimensions2.dim2);
        deleteMatrix(matrix3, dimensions2.dim2);
        deleteMatrix(matrix1, dimensions1.dim1);
        deleteMatrix(matrix2, dimensions2.dim1);
        return 0;
    }
}

struct Dimensions enterDimensions(void) {
    struct Dimensions dimensions;
    printf("enter dim 1: ");
    if (scanf("%d", &dimensions.dim1) != 1) {
        printf("invalid input\n");
        exit(1);
    }
    printf("enter dim 2: ");
    if (scanf("%d", &dimensions.dim2) != 1) {
        printf("invalid input\n");
        exit(1);
    }
    return dimensions;
}

int **allocateMatrix(int dim1, int dim2) {
    if (dim1 <= 0 || dim2 <= 0) {
        printf("invalid dimensions: %d,%d\n", dim1, dim2);
        exit(1);
    }
    int **matrix = calloc(dim1, sizeof(int *));
    if (!matrix) {
        printf("allocation failed\n");
        exit(1);
    }
    for (int i = 0; i < dim1; i++) {
        matrix[i] = calloc(dim2, sizeof(int));
        if (!matrix[i]) {
            printf("allocation failed\n");
            exit(1);
        }
    }
    return matrix;
}

int **createMatrix(int dim1, int dim2) {
    int **matrix = allocateMatrix(dim1, dim2);

    for (int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            printf("enter (%d,%d): ", i, j);
            if (scanf("%d", &matrix[i][j]) != 1) {
                printf("invalid input\n");
                exit(1);
            }
            //printf("%d\n", matrix[i][j]);
        }
    }
    return matrix;
}

void deleteMatrix(int **matrix, int dim1) {
    if (matrix == NULL)
        return;
    for (int i = 0; i < dim1; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

void displayMatrix(int **matrix, int dim1, int dim2) {
    if (matrix == NULL)
        return;
    for (int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            printf("[%d]", matrix[i][j]);
        }
        printf("\n");
    }
}

int **multiply(int **matrix1, int **matrix2, int dim11, int dim12, int dim22) {
    if (matrix1 == NULL || matrix2 == NULL)
        return NULL;
    int **matrix3 = allocateMatrix(dim11, dim22);
    for (int i = 0; i < dim11; i++) {
        for (int j = 0; j < dim22; j++) {
            int cij = 0;
            for (int k = 0; k < dim12; k++) {
                cij += matrix1[i][k] * matrix2[k][j];
            }
            matrix3[i][j] = cij;
        }
    }
    return matrix3;
}
© www.soinside.com 2019 - 2024. All rights reserved.