在C89中重写多维VLA

时间:2016-01-17 21:49:01

标签: c pointers malloc c99 c89

我为一个开源项目重写了一堆C99 VLA,以便在Visual Studio中获得支持。所以我有很多陈述,如

void somefunc(double var[r]){...}

我改写为

void somefunc(double *var) {
     var = malloc(sizeof(double) * r);
     ...
     free(var);
}

我认为这是正确的方法。
问题是我开始看到一些更复杂的VLA声明让我感到难过。例如:

double *(*var)[length1][length2][length3] = malloc(sizeof(double *[length4][length1][length2][length3]));

所以对我来说这基本上看起来像一个5维数组。 由于在sizeof()函数中使用了变量,这在C89中显然是非法的。

我对如何改写这个的猜测是:

double *****var = malloc(sizeof(double ****) * length1);
      for(int i = 0; i<length1; i++) {
            var[i] = malloc(sizeof(double ***) * length2);
            for(int j = 0; j<length2; j++) {
                 var[i][j] = malloc(sizeof(double **) * length3);
                      for(int k = 0; k<length3; k++) {
                           var[i][j][k] = malloc(sizeof(double *) * length4);
                      } 
            }
      }

尽管很乱,但这是我对如何重写上述陈述的最佳猜测。这在技术上是否正确,是否有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

这是我的尝试:

double***** var = malloc(sizeof *var * length4);

for (int i = 0; i < length4; ++i)
{
    var[i] = malloc(sizeof *var[i] * length1);

    for (int j = 0; j < length1; ++j)
    {
        var[i][j] = malloc(sizeof *var[i][j] * length2);

        for (int k = 0; k < length2; ++k)
        {
            var[i][j][k] = malloc(sizeof *var[i][j][k] * length3);

            for (int l = 0; l < length3; ++l)
            {
                var[i][j][k][l] = NULL;     
                // var[i][j][k][l] is a double* - you can allocate some room for a double here, or assign the address of an existing variable
            }
        }
    }
}

与您的相似,但请注意我在第一个length4中如何使用malloc。如果您查看原始声明,var指针double*的三维数组。正如我们可以从右侧的malloc调用中推断出的那样,length4这样的数组的内存被分配,因此您可以将var视为一个length4三维数组数组double*

我仍然认为,任何将这些东西放入生产代码的人都应当当场拍摄(好吧,作为维护者,你可以原谅)。

IIRC在for内声明变量并不是有效的C89,但您可以将这些变量移到您的范围顶部。

请注意,正如@immibis在评论中指出的那样,您的首次转化很可能是一个错误; double *var是函数的一个参数,这意味着它是按值传递的,因此您在函数内部对函数进行的任何更改都不会在外部可见,并且最重要的是,malloc free 1}}一些记忆,用它做事,然后double**它。即使您正在修改传递的指针 - 这将要求参数类型为malloc - 仍然不需要传递变量,因此您可以在本地独占使用它。你很可能想要{{1}}函数外部的内存,并传递一个有效的指针(希望大小)。