在C中动态分配二维数组

时间:2014-10-29 10:06:57

标签: c arrays dynamic-allocation

我一直在使用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;
}

有人能指出我在那里出了什么问题吗?

4 个答案:

答案 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}}而不是newdelete

<小时/> 1。无论如何,截至1989年的标准;在C89之前,mallocfree返回malloc而不是calloc,因此对于C89之前的编译器,需要 。 MSVC支持C89标准,因此您不需要演员

答案 3 :(得分:0)

更改

*cord = (int**)malloc(lines*sizeof(int*));

cord = malloc(lines*sizeof(int*));

此外,您不是分配2D数组,而是分配基于指针的查找表。要分配真实的2D数组,请执行like this