在 C++ 中创建一个大数组 [重复]
Posted
技术标签:
【中文标题】在 C++ 中创建一个大数组 [重复]【英文标题】:Create a big array in C++ [duplicate] 【发布时间】:2011-03-09 10:22:38 【问题描述】:可能重复:Segmentation fault on large array sizes
大家好
我正在尝试使用 C++ 在 VS 2010 中创建一个非常大的数组。
当我尝试创建如下所示的数组时
int dp[4501][4501]
or
int dp[1000][1000]
它抛出异常“堆栈溢出” 然后我把它改成:
int dp[100][100]
一切都很好。
那么如果我想创建一个像上面这样的大数组,我应该怎么做呢?
最好的问候,
【问题讨论】:
【参考方案1】:你应该使用动态分配:
typedef std::vector<int> int_vector;
int_vector dp(10000);
可以通过嵌套数组来模拟双精度数组:
typedef std::vector<int_vector> int_double_vector;
int_double_vector dp(4501, int_vector(4501));
【讨论】:
我不喜欢 typedef 这样使用。为什么?很简单:您的int_array
实际上是一个int vector,而您的int_double_array
与一个double 完全没有关系。 (另外,我必须进行 两次 查找才能找出它实际上是什么。) 糟糕的风格,恕我直言。仅将 typedef 用于非常复杂或神秘的事物,即使这样,也仅当它们的声明在您的代码中频繁出现时。 (我会想到成对向量映射的迭代器或函数指针。)对于只使用了两三次的声明,它们是一种混淆工具。
@Dev:我认为你对它的阅读方式太过分了。 :) 快乐的? Double 的意思是二,只是巧合的是双精度浮点类型称为 double,不要让它妨碍英语定义。代码是为人类服务的。
int_double_vector 的措辞真的很烂。你应该像 2d_int_vector 那样做某事。除了 typedef 没有问题之外,它比使用 std::vector<:vector> >::iterator... 要好得多
"double" 在编程上下文中通常(并且在“编程中的类型”上下文中几乎完全)表示“双精度浮点”。
@ypnos:经过 10 年的 C++ 维护编码,我实际上更喜欢没有 typedef 的代码。是的,这包括std::vector< std::vector< int > >::const_iterator
和类似的东西。根据我的经验,有用的 typedef 与混淆的 typedef 的比率约为 20 分之一。【参考方案2】:
所以如果我想创建一个大数组 像上面一样,我该怎么办?
避免在这些情况下使用堆栈(换句话说,避免在函数内部工作时创建类似这些不是堆分配的数组)。只是给你一个想法,我的线程本地堆栈只有 16 KB 大。 4501 * 4501 * 4(假设每个 int 4 字节)= ~81 MB。
请考虑这样的事情:
typedef vector<int> Row;
typedef vector<Row> Matrix;
Matrix dp(4501, Row(4501) );
如果你想创建一个 10x50 矩阵:
Matrix dp(10, Row(50) );
您可以像使用普通 dp 数组一样使用它,但它不会溢出堆栈。这一个将被分配并自动释放到堆中/从堆中释放,因此您在使用时不必担心堆栈溢出。
dp[5][10] = 123;
祝你好运!
[编辑] boost 中也有矩阵解决方案值得研究,但考虑到主题的性质,建议 boost 可能有点为时过早。
【讨论】:
【参考方案3】:您的声明看起来有点像dp
将用作矩阵。在这种情况下,专用(密集)矩阵类(如boost::numeric::ublas::matrix
)是最简单的解决方案,比向量向量更容易且更局部。如果矩阵是稀疏填充的,请改用稀疏矩阵类。
【讨论】:
【参考方案4】:如果您想避免使用new[]
,或避免使用std::vector
,请将数组设为全局。这会将数组放在堆上,不会发生堆栈溢出。
【讨论】:
请不要使用全局变量。在这种情况下,有无数更好的解决方案(vector
不是唯一的容器类)。
@Philipp:全局变量在某些情况下很有用。而且,如果您将全局变量放入命名空间(或在结构或类中创建静态全局成员),那么它们绝对没有问题。另一种解决方案是将变量(在函数内声明)设为静态。
全局变量通常会导致比它们解决的问题更多的问题。如果您想要的只是堆分配,它们绝对不是解决方案。
我猜 OP 正在尝试解决一些编程问题,其中获得“正确”就是一切。对于只愿意让他/她的解决方案“正确”的人来说,像专业程序员一样编码是过度的。此外,使用容器代替普通数组将需要更多时间来解决问题。一旦我遇到这样的问题。我使用了 std::vector 并超出了时间限制。我只是用普通数组替换了向量并通过了我的解决方案。
-1 用于提供“不良做法”解决方案。【参考方案5】:
您的堆栈溢出了太多位。你必须把它们排干。最好放在一堆其他位上。我建议 /F67108864。 /F 代表“F'ing hell 为什么堆栈与堆相比如此之小?”。 67108863 是任意的。
【讨论】:
我们需要标签来回答问题。 funny-but-wrong-approach 之类的标签 我认为设置一个足够大的堆栈大小来处理数组是一个好方法。编译器的斜杠 /F 选项就是这样做的。在答案中添加幽默并不会使其无效并使其成为错误的方法。【参考方案6】:来自 Parashift 常见问题的文本:Why should I use container classes rather than simple arrays?
编辑:
看看***线程:
When would you use an array rather than a vector/string? Why use iterators instead of array indices?
【讨论】:
【参考方案7】:使用动态分配或 STL。最近有一个关于一个非常相似的问题的帖子。见this。
【讨论】:
【参考方案8】:把它放在theheap。
【讨论】:
除非不直接使用new
或malloc
。
它们并没有明显的问题,尤其是在理解目标的层面上。
它们并没有什么明显的错误,但是“new int[4501][4501]”是错误的,这就是 GMan 的意思。
使用手动内存管理是不好的编程,把它包起来。 std::vector
就是为此目的而存在的。以上是关于在 C++ 中创建一个大数组 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C++ 中创建 OpenOffice 文档 [重复]