C语言矩阵乘法作业malloc分配内存打印出现非0值33问题求助
C语言矩阵乘法作业问题定位
开发约束
- 代码中禁止使用方括号,必须使用指针 notation 操作
- 矩阵A、B、C必须定义为单整数指针变量(
int *A, *B, *C) - 仅可使用main函数及头文件指定的函数
- 必须使用
gcc -ansi -Wall -o p2 p2.c命令编译
问题描述
暂未实现矩阵乘法功能,当前遇到问题:使用malloc为矩阵分配内存并将所有元素赋值为0后,输出结果中部分位置出现值33而非预期的0,自行编写的debug遍历逻辑检测矩阵所有元素均为0,怀疑问题出在打印逻辑,33为ASCII码对应的感叹号,无明确关联线索。
相关代码与文件
p2.h(教师提供)
#include <stdio.h> #include <stdlib.h> /* This function reads m, n, and p from the datafile. It then allocates the correct amount of memory required for matrices A, B, and C. Then matrices A and B are filled from the datafile. The values for m, n, and p are passed by reference, and are thus filled in by this function PARAMETERS in order are: int ** matrix A int ** matrix B int ** matrix C int * m The number of rows in matrix A int * n The number of columns in matrix A and The number of rows in matrix B int * p The number of columns in matrix B char * The name of the datafile, from the command line */ void read_matrices(int **, int **, int **, int *, int *, int *, char *); /* This function prints a matrix. Rows and columns should be preserved. PARAMETERS in order are: int * The matrix to print int The number of rows in the matrix int The number of columns in the matrix */ void print_matrix(int *, int, int); /* The two matrices A and B are multiplied, and matrix C contains the result. PARAMETERS in order are: int * Matrix A int * Matrix B int * Matrix C int m int n int p */ void mult_matrices(int *, int *, int *, int, int, int);
p2.c(当前实现)
#include <stdio.h> #include <stdlib.h> #include "./p2.h" /* constants for testing */ #define cM 3 #define cN 2 #define cP 5 int main(int argc, char **argv) { if (argc < 2) { printf("Must include an argument.\n"); exit(1); } char *path = *(argv + 1); int *m = (int *) malloc(sizeof(int)); int *n = (int *) malloc(sizeof(int)); int *p = (int *) malloc(sizeof(int)); *m = cM; *n = cN; *p = cP; int i,j; /* loop counters */ /* allocate space for 2d pointer arrays */ int **A = NULL; A = (int **) malloc(*m * sizeof(int *)); for (i = 0; i < *m; i++) { *(A+i) = (int *) malloc(*n * sizeof(int)); } int **B = NULL; B = (int **) malloc(*n * sizeof(int *)); for (i = 0; i < *n; i++) { *(B+i) = (int *) malloc(*p * sizeof(int)); } int **C = NULL; C = (int **) malloc(*m * sizeof(int *)); for (i = 0; i < *m; i++) { *(C+i) = (int *) malloc(*p * sizeof(int)); } /* write data to A */ for (i = 0; i < *m; i++) { for (j = 0; j < *n; j++) { *(*(A+i)+j) = 0; } } /* testing a */ for (i = 0; i < *m; i++) { for (j = 0; j < *n; j++) { if (*(*(A+i)+j) != 0) { printf("[x]"); } else { printf("[0]"); } } } printf("\n"); /* write data to B */ for (i = 0; i < *n; i++) { for (j = 0; j < *p; j++) { *(*(B+i)+j) = 0; } } /* testing b */ for (i = 0; i < *n; i++) { for (j = 0; j < *p; j++) { if (*(*(B+i)+j) != 0) { printf("[x]"); } else { printf("[0]"); } } } printf("\n"); /* write data to C */ for (i = 0; i < *m; i++) { for (j = 0; j < *p; j++) { *(*(C+i)+j) = 0; } } /* testing c */ for (i = 0; i < *m; i++) { for (j = 0; j < *p; j++) { if (*(*(C+i)+j) != 0) { printf("[x]"); } else { printf("[0]"); } } } printf("\n"); printf("Matrix A: \n"); print_matrix(*A, *m, *n); printf("Matrix B: \n"); print_matrix(*B, *n, *p); printf("Matrix C: \n"); print_matrix(*C, *m, *p); return 0; } void read_matrices(int **A, int **B, int **C, int *m, int *n, int *p, char *path) { FILE *fptr; fptr = fopen(path, "r"); if (fptr == NULL) { printf("Cannot open file: ./p2 [filename].txt\n"); exit(1); } /* get first 3 numbers from file, set m,n,p */ *m = fgetc(fptr); fgetc(fptr); *n = fgetc(fptr); fgetc(fptr); *p = fgetc(fptr); fgetc(fptr); /* read first matrix */ /* 1) calculate matrix size m x n * 2) loop through malloc'ed matrix * 3) each loop, insert char in loc * 4) if next char NOT 10/32, add nextchar*10 to value in loc */ char cur; while ( (cur = fgetc(fptr)) != EOF ) { if (cur == 10 || cur == 32) { /* do nothing :) */ } else { *m = cur; *n = cur; *p = cur; break; } } printf("m: %c\n", *m); printf("n: %c\n", *n); printf("p: %c\n", *p); printf("next: %c\n", fgetc(fptr)); fclose(fptr); } void print_matrix(int *X, int rows, int cols) { int r, c; int k = 0; for (r = 0; r < rows; r++) { for (c = 0; c < cols; c++) { printf("\t%d", *(X+k)); k++; } printf("\n"); } } void mult_matrices(int *A, int *B, int *C, int m, int n, int p) { }
测试数据文件d2.txt
3 2 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14
程序运行输出
[0][0][0][0][0][0] [0][0][0][0][0][0][0][0][0][0] [0][0][0][0][0][0][0][0][0][0][0][0][0][0][0] Matrix A: 0 0 0 0 0 0 Matrix B: 0 0 0 0 0 0 33 0 0 0 Matrix C: 0 0 0 0 0 0 33 0 0 0 0 0 0 0 33
根因定位
- 核心错误:违反开发约束的矩阵存储要求
约束明确要求矩阵为int *单指针类型,对应一维连续内存存储。你当前定义的是int **二级指针,每一行单独调用malloc分配内存,不同行的内存地址不连续。
你自己写的debug遍历逻辑是通过二级指针逐行访问,只访问了每行malloc分配的合法内存范围,所以检测到所有元素都是0;而print_matrix函数接收的是单指针,默认矩阵是连续一维内存,遍历完第一行后直接向后越界访问了不属于当前矩阵的内存区域,这些区域的随机值就出现了33这类异常数值。 - 其他待修复问题
- 未调用教师指定的
read_matrices函数,自行硬编码了测试参数 read_matrices当前实现错误:用fgetc读取的是字符ASCII码,直接赋值给m/n/p会导致存储的是字符编码而非实际数值,需要用fscanf或者自行转换字符到整数- 矩阵内存分配逻辑需要重构为单指针连续内存:比如A矩阵分配
malloc(m*n*sizeof(int)),第r行c列的元素访问方式为*(A + r*n + c)
内容的提问来源于stack exchange,提问作者redwood
相关产品推荐
相关产品推荐

