在这种情况下 malloc 和 calloc 之间的区别?

Difference between malloc and calloc in this case?

这是一段C语言中两个方阵相乘的代码

void multiply()函数中使用malloccalloc有什么区别? 使用 malloc 时,我得到的是垃圾值,但 calloc 提供了正确的答案。 只有第一行输出垃圾值,所以与 calloc 相比,malloc 在堆中分配 space 的方式有问题吗?

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

int *getArray(int);
void display(int *, int, int);
void multiply(int *, int *, int);

int main() {
    int n;
    printf("enter dimension of square matrix:\n");
    scanf("%d", &n);
    int *arr1;
    int *arr2;
    arr1 = getArray(n);
    display(arr1, n, n);
    printf("\n now give input for next array");
    arr2 = getArray(n);
    display(arr2, n, n);
    printf("\n\n\n");
    multiply(arr1, arr2, n);
    return 0;
}

int *getArray(int n) {
    int *arr = (int *)malloc(n * n * sizeof(int));
    printf("\n");
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", (arr + i * n + j));
        }
    }
    /*for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf(" %d ", *(arr + i * n + j));
        }
        printf("\n");
    }*/
    return arr;
}
    
void display(int *arr, int row, int col) {
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            printf(" %d ", *(arr + i * row + j));
        }
        printf("\n");
    }
}

void multiply(int *arr1, int *arr2, int n) {
    int *arr = (int *)calloc(n * n, sizeof(int));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                *(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
            }
        }
    }
    printf("product of above matrices = \n\n");
    display(arr, n, n);
}

假设大小计算准确,使用 malloc() 和使用 calloc() 分配内存的唯一功能差异是后者将块初始化为所有位 0,而前者没有。

所有位 0 表示数组中的所有 int 值都初始化为 0

multiply函数中的内层循环只增加行i和列j的元素,因此该函数依赖于将数组元素隐式初始化为0。 calloc() 这样做,但不是 malloc() 所以你肯定需要使用 calloc().

另请注意以下备注:

  • displayij 处的矩阵元素偏移量的计算应为 printf(" %5d ", *(arr + i * col + j));
  • multiply 应该 return arrdisplay() 应该在 main 函数中调用。
  • 您应该检查 scanf()malloc() and calloc()` 失败
  • 你应该释放分配的内存
  • 指向未被函数修改的对象的指针参数应 const 限定,以便可以使用指向 const 对象的指针调用函数。

这是修改后的版本:

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

int *getArray(int);
void display(const int *, int, int);
int *multiply(const int *, const int *, int);

int main() {
    int n;
    printf("enter dimension of square matrix:\n");
    if (scanf("%d", &n) != 1)
        return 1;
    printf("\n now give input for the first array");
    int *arr1 = getArray(n);
    if (!arr1)
        return 1;
    display(arr1, n, n);
    printf("\n now give input for the second array");
    int *arr2 = getArray(n);
    if (!arr2)
        return 1;
    display(arr2, n, n);
    printf("\n\n\n");
    int *arr = multiply(arr1, arr2, n);
    if (!arr)
        return 1;
    printf("product of above matrices = \n\n");
    display(arr, n, n);
    free(arr1);
    free(arr2);
    free(arr);
    return 0;
}

int *getArray(int n) {
    int *arr = malloc(sizeof(int) * n * n);
    if (arr == NULL)
        return NULL;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (scanf("%d", (arr + i * n + j)) != 1) {
                free(arr);
                return NULL;
            }
        }
    }
    return arr;
}
    
void display(const int *arr, int row, int col) {
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            printf(" %5d ", *(arr + i * col + j));
        }
        printf("\n");
    }
}

int *multiply(const int *arr1, const int *arr2, int n) {
    int *arr = calloc((size_t)n * n, sizeof(int));
    if (arr == NULL)
        return NULL;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                *(arr + i * n + j) += (*(arr1 + i * n + k)) * (*(arr2 + k * n + j));
            }
        }
    }
    return arr;
}