我一直在使用malloc()在C中编译二维数组;
尝试在Microsoft Visual Studio Express 2013中编译我的代码我不断收到错误'类型为" int **"无法分配到" int *"'
类型的实体这是我的代码:
int main() {
int lines = 0;
int **cord;
FILE *f = fopen("data.txt", "r");
if (f == NULL) return 0;
fscanf(f, "%d", &lines);
printf("%d", lines);
*cord = (int**)malloc(lines*sizeof(int*));
int i = 0;
for (i; i < lines; ++i)
{
cord[i] = (int*)malloc(2 * sizeof(int));
fscanf(f, "%d", cord[i][0]);
fscanf(f, "%d", cord[i][1]);
}
i = 0;
return 0;
}
有人能指出我在那里出了什么问题吗?
答案 0 :(得分:2)
首先,不要强制转换malloc()
的返回值。
关于错误,在您的代码中,首先需要将内存分配给cord
,然后分配到cord[i]
(或*cord
)。
而不是使用
*cord = malloc(lines*sizeof(int*));
,
使用
cord = malloc(lines*sizeof(int*));
另外,添加NULL
检查malloc()
是否成功,例如
if (!cord) //also for cord[i]
{
//print error and return / exit;
}
答案 1 :(得分:2)
*cord = (int**)malloc(lines*sizeof(int*));
错误,您正在取消引用未初始化的指针cord
。请编码
cord = malloc(lines*sizeof(int*));
if (!cord) { perror("malloc cord"); exit (EXIT_FAILURE); }
永远不要忘记测试malloc
的失败(您还应该在分配cord[i]
时对其进行测试)
顺便说一句,您应该在编译器中启用所有警告和调试信息。如果使用最近的GCC作为gcc -Wall -Wextra -g
,则会因第一个错误而被警告。
另外,如果你想在C中使用矩阵,最好使用一维数组来表示它。
答案 2 :(得分:1)
*cord = (int**)malloc(lines*sizeof(int*));
变量cord
的类型为int **
,因此表达式 *cord
的类型为int *
。您正在将malloc
的结果投射到int **
。因此,您尝试将类型int **
的值分配给类型为int *
的表达式,这是一个错误。该行应写为
cord = malloc( lines * sizeof *cord ); // note no cast, operand of sizeof
样式说明 - 空白是你的朋友。用它。你的眼睛永远不会永远20岁。
如果在编译时知道列数(在这种情况下似乎是这样),则可以进行一步分配:
int (*cord)[2];
...
cord = malloc( lines * sizeof *cord );
if ( cord )
{
for ( int i = 0; i < lines; i++ )
{
fscanf( f, "%d", &cord[i][0] );
fscanf( f, "%d", &cord[i][1] );
}
...
free( cord );
}
else
// handle allocation failure
变量cord
的类型为&#34;指向{-1}}&#34;的2元素数组,因此表达式int
具有类型&#34; 2元素数组*cord
&#34;。 int
给出了每个子数组所需的字节数,因此sizeof *cord
给出了整个2D数组所需的总字节数。
优点 - 单步分配(意味着单步重新分配),并且数组中的所有行都是连续的。
缺点 - 如果内存碎片足够,非常大的数组可能会失败,要求您在编译时知道列数或者您的编译器支持可变长度数组(在C99中引入)并且从C2011开始是可选的)。
通常,您的lines * sizeof *cord
语句应写为
malloc
或
T *ptr = malloc( N * sizeof *ptr ); // calloc( N, sizeof *ptr )
C并不要求您投射T *ptr = NULL;
...
ptr = malloc( N * sizeof *ptr ); // calloc( N, sizeof *ptr );
1 的结果。 C ++ 确实需要它,因为它不允许隐式转换malloc/calloc
指针,但如果您正在编写C ++,那么您应该使用void
和{{ 1}}而不是new
和delete
。
<小时/> 1。无论如何,截至1989年的标准;在C89之前,
malloc
和free
返回malloc
而不是calloc
,因此对于C89之前的编译器,需要 。 MSVC支持C89标准,因此您不需要演员
答案 3 :(得分:0)
更改
*cord = (int**)malloc(lines*sizeof(int*));
到
cord = malloc(lines*sizeof(int*));
此外,您不是分配2D数组,而是分配基于指针的查找表。要分配真实的2D数组,请执行like this。