我正试图以以下方式动态分配2D阵列:
- 有一个指针检查器
void chk (void* p) {
if (p == NULL) {
fprintf(stderr, "Couldn't allocate.n");
exit (0);
}
}
- 读取行数
scanf("%d", &n);
- 为数组(
v
(和保持行大小(u
(的数组分配必要的内存
v = (int**) calloc(n, sizeof(int));
chk(v);
u = (int*) calloc(n, sizeof(int));
chk(u);
- 对于每一行,读取其中的元素数(
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]);
- 打印存储在
u
中的值
for (i = 0; i < n; i++)
printf("%dn", u[i]);
- 释放内存
free(u);
for (i = 0; i < n; i++)
free(v[i]);
free(v);
此代码在Windows中正确运行(中未注释free部分(,但在Linux中无法做到这一点!在在线编译器中运行代码时(因此在Linux下(,我们可以看到两件事:
-
u[0]是垃圾,u[1]是0。
u[2]。。。,你没事。
-
有了免费部分的评论,1。是可能的。然而,如果免费没有评论,我们会得到
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
的返回值进行强制转换是不必要的,而且会适得其反。