是什么导致 Windows 和 Linux 之间 malloc() 和 free() 的行为差异?

What causes this difference in behaviour for malloc() and free() between Windows and Linux?

我正在尝试通过以下方式动态分配二维数组:

  1. 有一个指针检查器。

void chk (void* p) {
    if (p == NULL) {
        fprintf(stderr, "Couldn't allocate.\n");
        exit (0);
    }
}

  1. 读取行数

scanf("%d", &n);

  1. 为数组的数组 (v) 和保持行大小的数组 (u) 分配必要的内存。

v = (int**) calloc(n, sizeof(int));
chk(v);
u = (int*) calloc(n, sizeof(int));
chk(u);

  1. 对于每一行,读取其中的元素数 (u[i])。为当前行(v[i])分配必要的内存,并读取元素。

scanf("%d", &u[i]);
v[i] = (int*) calloc(u[i], sizeof(int));
chk(v[i]);
for (j = 0; j < u[i]; j++)
    scanf("%d", &v[i][j]);

  1. 打印存储在u中的值。

for (i = 0; i < n; i++)
    printf("%d\n", u[i]);

  1. 释放内存。

free(u);
for (i = 0; i < n; i++)
    free(v[i]);
free(v);

This code 在 Windows 中运行正确( 自由部分未注释 ),但在 Linux 中运行失败!在 运行 在线编译器中的代码(在 Linux 下),我们可以看到两件事:

  1. u[0]是垃圾,u[1]是0。

    u[2], ..., u[n] 没问题。

  2. 随着空闲部分的注释,1.是可能的。然而,如果 free 没有被评论,我们会得到 Abort signal from abort(3) (SIGABRT).

后两点怎么可能?是什么导致了 Windows 和 Linux 之间的差异?如何解决?

谢谢!

这是一个问题:

v = (int**) calloc(n, sizeof(int));

v应该是int还是int *的数组?您的转换和 sizeof 操作数不一致。解决此问题的最佳方法是丢失演员表并使用 sizeof *v 作为您的尺寸:

v = calloc( n, sizeof *v );

u 和每个 v[i] 的分配执行相同的操作 - 一般习惯用法是

T *p = calloc( n, sizeof *p );

T *p;
...
p = calloc( n, sizeof *p );

除非您将此代码编译为 C++ 或 C89 之前的代码,否则对 calloc 的 return 值进行强制转换是不必要的,而且会适得其反。