堆栈中的动态数组?
Posted
技术标签:
【中文标题】堆栈中的动态数组?【英文标题】:Dynamic array in Stack? 【发布时间】:2009-07-30 04:59:30 【问题描述】:这是正确的吗? 这是用 g++ (3.4) 成功编译的。
主函数() 诠释 x = 12; 字符 pz[x];【问题讨论】:
【参考方案1】:这是您对所有其他问题的综合答案:
您现在的代码不是标准 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);
【讨论】:
【参考方案2】:从技术上讲,这不是 C++ 的一部分。您可以在 C99 (ISO/IEC 9899:1999) 中执行可变长度数组,但它们不是 C++ 的一部分。正如您所发现的,一些编译器支持它们作为扩展。
【讨论】:
【参考方案3】:G++ 支持允许动态大小数组的 C99 功能。它不是标准的 C++。 G++ 有 -ansi
选项,它关闭了一些 C++ 中没有的特性,但这不是其中之一。要让 G++ 拒绝该代码,请使用 -pedantic
选项:
【讨论】:
【参考方案4】:如果你想要一个动态数组在栈上:
void dynArray(int x)
int *array = (int *)alloca(sizeof(*array)*x);
// blah blah blah..
【讨论】:
它有效,但我想从“man alloca”中添加以下引用:“alloca() 函数依赖于机器和编译器;不鼓励使用。”【参考方案5】:在堆栈上分配可变长度的数组是一个好主意,因为它速度快并且不会使内存碎片化。但遗憾的是,C++ Standard 不支持它。您可以通过对alloca
函数使用模板包装器来做到这一点。但是使用alloca
并不是真正符合标准。
如果您想避免内存碎片和加速内存分配,标准方法是使用带有 自定义分配器 的 std::vector。查看boost::pool_alloc 以获得快速分配器的良好示例。
【讨论】:
【参考方案6】:实际上,如果你想创建一个动态数组,你应该使用std::vector,如:
#include如果您只是对语法感到好奇,那么您正在寻找的是:
//... int* 数组 = 新的 int[大小]; // 用数组做事... 删除 [] 数组; //...这些都没有分配本地存储。标准 C++ 目前不支持使用本地存储自动分配的动态大小的数组,但当前的 C 标准支持。
【讨论】:
new 不是在堆上分配内存吗?鉴于问题的标题,我的印象是 OP 希望将其分配在堆栈上。 并没有改变矢量是正确解决方案的事实。在这种情况下,他不能得到他想要的东西。向量是最接近的。 (不,我没有考虑在 C++ 上下文中使用 alloca) 对于在某些情况下需要关键性能的应用程序,如果编译器不支持“int array[x]”语法,alloca 绝对是正确的答案。基于堆栈的分配,通常只是从堆栈指针中减去一条指令,比堆分配要快得多。 正如我所说,它们都不使用本地存储(堆栈),而是使用动态存储(堆)。顺便说一句,如果我没记错的话,C++ 标准特别没有提到堆栈或堆,而是使用术语本地/自动存储和动态存储。 是的,POD 在这里工作得很好,这是 OP 的例子。对于 C++ 对象,您必须就地构造它们并显式破坏它们。与显式构造/破坏的轻微烦恼相比,性能提升是否值得由程序员决定。以上是关于堆栈中的动态数组?的主要内容,如果未能解决你的问题,请参考以下文章