繁体   English   中英

可以使用变量来定义c中堆栈上数组的大小吗?

[英]Can a variable be used to define the size of an array on the stack in c?

我有一种情况,我希望我的程序读取一些数字,这些数字将定义二维数组的大小(用作矩阵)。 我最初认为,唯一的方法是使用malloc调用将数组放在堆上,如下所示:

matrixElement* matrix = malloc(sizeof(matrixElement) * numRows * numCols);

其中numCols和numRows是前面读过的整数,而matrixElement是一些任意类型。 我的理由只是写作:

matrixElement matrix[numRows][numCols];

因为编译器无法知道要为函数调用分配多少堆栈空间,所以不会工作。 事实证明我错了,因为以下代码编译并运行:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int x, y;
    scanf("%d", &x);
    scanf("%d", &y);

    double arr[x][y];

    printf("Made an array of size %d by %d, total memory %fKb\n", 
            sizeof(arr) / sizeof(arr[0]), 
            sizeof(arr[0]) / sizeof(arr[0][0]),
            (float) sizeof(arr) / 1024.0f);

    return 0;
}

对于x和y有足够大的数字输入,这最终会产生段错误,但我也非常惊讶地看到我可以使用此代码创建一个1000x1000数组。

谁能解释一下这里发生了什么?

编译器是否只是为数组分配了一堆空间,即使它不知道将使用多少空间?

这种行为是由ANSI C指定还是只是gcc自己做的事情?

此功能已在C99中添加。 数组在堆栈上分配的方式类似于调用alloca() 可能存在一些微妙的差异; 检查编译器文档以获取信息。

GCC文档描述了它们的实现。

C99增加了对可变长度数组(有时称为“VLA”)的支持。 许多C编译器在C99之前也支持这一点。 许多人还支持“alloca”功能,它做了同样的事情,但是方式稍微不那么方便。

典型的实现分配“正确”的空间量。 基本上,堆栈指针只是根据可变长度数组的大小进行调整。 需要进行一些额外的簿记以确保堆栈指针在返回时“弹出”正确的数量,并且以正确的偏移量访问放置在堆栈上的自动变量。

您应该对块中间声明arr数组这一事实感到惊讶,因为您对其变量指定的大小感到惊讶。 两者都是C99语言规范的新功能。 两者都得到了GCC编译器的支持,作为C89 / 90的扩展已有一段时间了。 但在“经典”ANSI C中,两者都不合法,即C89 / 90。

如果您正在以C89 / 90模式编译代码(这是GCC中的默认模式),那么您确实正在处理GCC自行执行的操作。 如果您在-std=c99模式下编译代码,则表示您正在处理[相对]新的标准语言功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM