我制作了一个创建2d数组的程序。 以下代码适用于visual studio& turbo c:
#include<stdio.h>
#include<stdlib.h>
int **allocarr(int **arr, int row, int col){
int i;
arr=calloc(row, sizeof(int));
for(i=0; i<row; i++){
arr[i]=calloc(col, sizeof(int));
}
return arr;
}
void freearr(int **arr, int row, int col){
int i;
for(i=0; i<row; i++) free(arr[i]);
free(arr);
}
void printarr(int **arr, int row, int col){
int i, j;
for(i=0; i<row; i++){
for(j=0;j<col;j++){
printf("\t%d", arr[i][j]);
}
printf("\n\n");
}
}
int main(){
int **arr=NULL;
arr=allocarr(arr, 3, 3);
arr[2][2]=8;
printarr(arr, 3, 3);
freearr(arr,3, 3);
return 0;
}
但它不适用于mac os x gcc和mingw gcc。
一切都很好,没有任何警告和错误(-Wall&amp; -Wextra),
但它在运行时崩溃了......
在gdb和lldb中,它表示free()
释放了一个未分配的内存。
在分配一个指针数组后,当我在那之后分配内存时,正好有两个内存块(这是正确的单词吗?)将具有无法初始化的随机值。
我尝试在将其分配给指针数组之前分配另一个数组。 它打印正常(没有2个随机值),但在为其分配值时仍会偶尔崩溃。 为什么会这样?
答案 0 :(得分:2)
此
arr=(int **)calloc(row, sizeof(int));
应该是
arr = calloc(row, sizeof(int*));
(请注意,C and actually discouraged中不需要强制转换)
因此,在指针大小不是int
大小的实现中(例如在x64机器上),当您在已分配内存的边界外读取时,将调用未定义的行为。
您可能会考虑不使用显式类型作为sizeof
的操作数。
arr = calloc(row, sizeof*arr);
这使得编译器可以推断出类型并帮助您避免这样的错误。