【发布时间】:2016-01-17 21:49:00
【问题描述】:
我正在为一个开源项目重写一堆 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 维数组。
这在 C89 中显然是非法的,因为在 sizeof() 函数中使用了变量。
我对如何重写的猜测是:
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);
}
}
}
虽然很乱,但这是我对如何重写上述语句的最佳猜测。这在技术上是否正确,是否有更好的方法可以解决这个问题?
【问题讨论】:
-
如果你有这个
double *(*var)[length1][length2][length3] = malloc(sizeof(double *[length4][length1][length2][length3]));,你应该从头重写所有程序。 -
我建议你找到最初的开发者并拍摄他们,除非这是他们的玩笑。至于声明,这实际上是一个指向
double指针的三维数组的指针。 -
在 C89 中无法从字面上重新编码多维可变大小数组。您可以像@szczurcio 所做的那样使用指针数组“伪造”多维数组。但这对指针空间和潜在的缓存负载有开销。更忠实的转录是定义函数和/或宏,以在一维数组中进行索引运算并重新编码所有数组访问。也就是说,对于 MxNxP 数组 A,您将访问元素
A[i][j][k]作为A1d[(i * N + j) * P + k]。当然A1d分配有M*N*P元素。这就是为什么 vla 被添加到语言中的原因! -
您对第一个示例(使用
double var[r])的转换几乎肯定是错误的。 -
为 VS 编写一个插件以使用适当的 C 编译器而不是像
clang或gcc的 MinGW 版本,这被认为可能更容易和更有效率 ...