我可以用这种方式制作动态阵列吗?

vai*_*ter 4 c arrays dynamic-memory-allocation variable-length-array

所以我的代码是这样的:

int a, b;
printf("Give dimensions\n");
scanf("%d %d", &a, &b);
double array1[a][b];
printf("Give values\n");
int i, j;
for(i=0; i<a; i++)
{
    for(j=0; j<b; j++)
    {
        scanf("%lf", &array1[i][j]);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我被告知这是一种分配内存的错误方法,我应该使用malloc.我应该使用用户的维度创建一个动态数组.

编辑:程序的其余部分:

double sum=0;
for(i=0; i<a; i++)
{
    for(j=0; j<b; j++)
    {
        sum = sum + array1[i][j];
    }
    printf("Line %d: sum = %lf\n", i+1, sum);
    sum=0;
}
Run Code Online (Sandbox Code Playgroud)

Sto*_*ica 6

取决于你如何定义"正确".这是C99以来的合法C.

但问题是,如果ab太大,数组将溢出调用堆栈.如果这是一个可能的情况,你应该更喜欢malloc.与堆相比,调用堆栈通常被分配得相当小.所以这可能是建议的来源.

请注意,您仍然可以使用动态分配的数组来享受数组下标表示法:

double (*array)[b] = malloc(sizeof(double[a][b]));
Run Code Online (Sandbox Code Playgroud)

数组在一个连续的块中,VLA指针将导致a[i][j]引用正确的元素.


Sou*_*osh 5

不,这是完全正确和有效的方式,只要您使用支持可变长度数组的编译器版本/环境.

这是一个强制性功能,C99但再次选择C11.

使用VLA和"指针和内存分配器功能组合"之间的主要区别是

  • VLA是块范围的.VLA不在作用域之外,因此它不能从函数返回并在调用者中使用,这与指针和malloc方法不同.
  • 通常,VLA在堆栈中分配用于所有主要实现,因此尺寸受限.


Grz*_*ski 5

尽管C11 标准使 VLA 支持可选,但 C 编译器可以将其作为有效代码处理。

主要问题是实际上您无法检查分配是否成功,特别是当大小未知时。这也是它的主要优点malloc/calloc

double (*array1)[b] = malloc(a * sizeof(*array1));
if (!array1) {
     // handle allocation failure
}
Run Code Online (Sandbox Code Playgroud)