C ++动态大小的静态数组益智游戏

时间:2011-06-08 19:57:15

标签: c++ arrays dynamic static

在尝试向某人解释为什么C ++静态数组无法动态调整大小时,我发现gcc不同意我的看法。鉴于在编译时不知道数组的维 argc ,以下代码如何编译?

#include <iostream>
int main(int argc, char* argv[]) {
    int array[argc];
    for(int i = 0; i < argc; i++) array[i] = argv[i][0];
    for(int i = 0; i < argc; i++) std::cout << i << ": " << char(array[i]) << std::endl;
    //for(int i = 0; i < 100; i++) { std::cout << i << " "; std::cout.flush(); array[i] = 0; }
    return 0;
}

我使用gcc 4.2.1进行了测试,并指定了-Wall,而没有从编译器那里得到一个脏看。如果我取消注释最后一个循环,当我分配给 array [53] 时会出现段错误。

我之前在声明数组之前和之后放置了保护数组,并用零填充它们,确定程序必须将其堆栈的一部分废弃,但是gcc重新排序了变量。堆栈,这样我就无法观察到任何数据损坏。

显然,我并不是想让这段代码“运转”。我只是想了解为什么gcc甚至认为它可以编译代码。任何提示或解释都将非常感激。

更新:感谢所有人提供的有用且快速的回复!

5 个答案:

答案 0 :(得分:10)

可变长度数组(VLA)是C99的一部分,并且长期以来一直受到gcc的支持:

http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

请注意,在C90和C ++代码中使用VLA是非标准的,但gcc作为扩展支持。

答案 1 :(得分:6)

这是Variable Length Array,这是C99标准的一部分。它不是C ++的一部分。

您也可以使用alloca函数,该函数也不是标准C ++,但受到广泛支持:

int main(int argc, char* argv[])
{
    int* array = (int*) alloca( argc * sizeof(int) );
    array[0] = 123;
    // array automatically deallocated here. Don't call free(array)!
}

答案 2 :(得分:3)

这些被称为可变长度数组(自C99起可用)并且只能作为自动变量声明 - 尝试将static放在前面,编译器将拒绝它。它只涉及使用变量递增堆栈指针而不是使用常量偏移量,而不是更多。

在引入可变长度数组之前,使用alloca函数在堆栈上分配可变大小的对象。

答案 3 :(得分:2)

可变大小的基于堆栈的数组是G ++扩展,在那里完全合法。然而,它们不是标准的。在大多数实现中,基于堆栈的数组确实可以变化,但标准并没有强制要求。

答案 4 :(得分:2)

除了使用常量表达式之外,无法调整C ++中的数组。通过非常量大小的数组是C99的一部分或GCC强加给我们的可怕扩展。在编译C ++代码时,可以使用-pedantic标志去除大部分GCC废话。