c中的双数组语法

时间:2012-07-23 19:51:08

标签: c arrays

问题可能看起来非常简单,但我如何在c中声明一个返回double数组的函数。例如

char myfunction(int a, int b)
{
...
char d[a][b];
...
return d;
}

但它似乎不起作用(如果响应可以避免使用'malloc'和'free',那么理解这些基本用法会更有帮助)

最佳, Newben

4 个答案:

答案 0 :(得分:3)

  

但它似乎不起作用(如果响应可以避免使用'malloc'和'free',那么理解这些基本用法会更有帮助)

嗯,你不能因为你提议在函数返回后返回一个无效的指针。数组以自动存储持续时间声明,因此,一旦函数返回,对它的所有引用都是无效的。您无法从C中的函数返回数组。

如果您需要在函数中填充数据,请从函数中返回char** malloc

char **foo(int cols, int rows) {
  char **ret = malloc(rows * sizeof(char*));
  if(!ret)
    return ret;

  for(int i = 0; i < rows; ++i) {
    ret[i] = malloc(cols);
    /* error checking again for malloc,
       call free() on pointers 0...i upon failure.
       memset to 0 if you like */
  }

  return ret;
}

现在可以对返回值使用多维数组语法。

char **p = foo(10, 20);

// p[j] returns a pointer to char, p[j][k] returns a char
char elem = p[j][k];

答案 1 :(得分:1)

在这种情况下你无法避免malloc和free。问题在于声明

char d[a][b];

您正在堆栈上直接分配数组,因此当您的函数返回时,数组将被取消分配,并且您返回的地址无效。

使用类似的东西:

char** myfunction(int a, int b) {
    char** d = (char**)malloc(a * sizeof(char*));

    if (d ! = NULL) {
        for (int i = 0; i < b; i++) {
            d[i] = (char*)malloc(sizeof(char));

            if (d[i] == NULL) {
                for (int j = 0; j < i; j++) {
                    free(d[j]);
                }

                free(d);
                d = NULL;

                break;
            }
        }
    }

    return d;
}

答案 2 :(得分:1)

在C中,如果你想要一个函数创建一个数组并将其返回给它的调用者,你必须使用malloc或另一个动态分配内存的函数(例如{{1 }或calloc)。然后,您可以返回指向数组的指针。

realloc

另一方面,如果您只需要修改数组的值,最好将数组作为参数并在适当的位置进行修改。

char **make2dArray(int x, int y) {
    int i;
    char **array = calloc(x, sizeof(char*));
    for(i = 0; i < x; i++) {
        array[i] = calloc(y, sizeof(char));
    }
    return array;
}

请记住,一旦完成动态分配的内存,请为每个分配免费呼叫:

void modify2dArray(int x, int y, char **array) {
    int i, j;
    for(i = 0; i < x; i++) {
        for(j = 0; j < y; j++) {
            array[i][j] = 1;
        }
    }
}

以下是使用这些功能的原因:

void dealloc2dArray(int x, int y, char **array) {
    int i;
    for(i = 0; i < x; i++) {
        free(array[i]);
    }
    free(array);
}

请注意,动态分配函数(char **array = NULL; array = make2dArray(5,6); modify2dArray(5,6,array); dealloc2dArray(5,6); array = NULL; malloccalloc)可能会失败,返回NULL。我在每次分配后都没有检查NULL以节省空间,但通常的做法是确保分配成功。

答案 3 :(得分:1)

在C99中,C99分配真实2D阵列的正确方法,而不是其他答案中的仿真,就是执行以下操作:

char (*array)[cols] = malloc(cols * rows);

如果你必须在一个函数中这样做,对我来说最简单的方法似乎是

void * foo(int cols, int rows) {
  char (*ret)[cols] = malloc(rows * cols);
  // do something with it
  return ret;
}

调用它时,您必须更加小心地将维度赋予新变量

char (*array)[cols] = foo(cols, rows);

所有这一切都有一个优点,即一个简单的malloc用于分配一个连续的对象,并且你只需要在最后调用一个free来释放内存。