堆栈中的动态数组?

21

这个正确吗? 使用g++(3.4)编译成功。

int main()
{
    int x = 12;
    char pz[x]; 
}
6个回答

26

以下是所有其他答案的综合回答:

您现在的代码不是标准的C ++。它是标准的C99。这是因为C99允许您以这种方式动态声明数组。为了澄清,这也是标准的C99:

#include <stdio.h>

int main()
{
    int x = 0;

    scanf("%d", &x);

    char pz[x]; 
}

这不属于任何标准:

#include <iostream>

int main()
{
    int x = 0;
    std::cin >> x;
    char pz[x]; 
}

它不能成为标准的C++代码,因为那需要数组大小的常数,而且也不能是标准C代码,因为C语言没有 std::cin(或命名空间、类等)。

要使其成为标准C++代码,请按照以下方法操作:

int main()
{
    const int x = 12; // x is 12 now and forever...
    char pz[x]; // ...therefore it can be used here
}

如果你想要一个动态数组,你可以这样做:

#include <iostream>

int main()
{
    int x = 0;
    std::cin >> x;

    char *pz = new char[x];

    delete [] pz;
}

但你应该这样做:

#include <iostream>
#include <vector>

int main()
{
    int x = 0;
    std::cin >> x;

    std::vector<char> pz(x);
}

16

G++支持C99的动态数组特性,但这不是标准C++。G++有一个-ansi选项,可以关闭一些不在C++中的功能,但这不包括此功能。要使G++拒绝该代码,请使用-pedantic选项:

$ g++ -pedantic junk.cpp
junk.cpp: 在函数‘int main()’中:
junk.cpp:4: 错误:ISO C++禁止变量大小的数组‘pz’

15

从技术上讲,这不是C ++的一部分。您可以在C99(ISO / IEC 9899:1999)中使用可变长度数组,但它们不是C ++的一部分。正如您发现的那样,一些编译器支持它们作为扩展。


12

如果你想要在栈上创建一个动态数组:

void dynArray(int x)
{
    int *array = (int *)alloca(sizeof(*array)*x);

    // blah blah blah..
}

10
它可以工作,但我想添加以下来自“man alloca”的引用:“alloca()函数是机器和编译器相关的;不建议使用。” - Michael Aaron Safyan

8

在堆栈上分配可变长度的数组是一个好主意,因为它快速且不会导致内存碎片。但是,不幸的是,C++标准不支持这样做。您可以通过使用模板包装器来使用alloca函数实现这一点。但是,使用alloca并不真正符合标准。

标准方法是使用自定义分配器的std::vector,如果您想避免内存碎片并加速内存分配,请参考boost::pool_alloc以获取快速分配器的良好示例。


1
实际上,如果你想要创建一个动态数组,你应该使用std::vector,如下所示:
#include #include #include int main(int argc, char* argv[]) { int size; std::cin>>size; std::vector array(size); // do stuff with array ... return 0; }
如果你只是对语法好奇,那么你需要的是:
//... int* array = new int[size]; // Do stuff with array ... delete [] array; //...
这两种方法都没有使用本地存储分配。在标准C++中,不支持自动分配本地存储的动态大小数组,但是在当前的C标准中支持。

新建不是在堆上分配内存吗?我认为OP希望它在栈上分配,鉴于问题的标题。 - mrduclaw
1
无论如何,向量是正确的解决方案。在这种情况下,他得不到他所要求的东西。向量是最接近的。(不,我不考虑在C++上下文中使用alloca) - jalf
3
如果编译器不支持 "int array[x]" 语法,对于需要在某些情况下具有关键性能的应用程序,alloca 绝对是正确的答案。基于栈的分配通常只需要一个减去堆栈指针的指令,比堆内存分配方式要快得多。 - Jim Buck
1
没错,POD在这里表现得非常好,这是OP的例子。对于C++对象,您必须进行就地构造并显式销毁它们。由程序员决定是否值得在明确构造/销毁的轻微烦恼上获得性能提升。 - Jim Buck
向量不是正确的解决方案,呸。 - Enerccio
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接