我有一个从大型数组中读取数据的程序,我最初在 Visual Studio 中将程序分成两个单独的项目,每个项目都可以正常工作,但是当我尝试将它们放在一起时,程序的行为很有趣,跳过了一些步骤,而调试。我对 C++ 很陌生,所以我开始做一些研究,我发现也许我正在用那些巨大的数组填充堆栈,我应该尝试将它们放在堆上。
我决定为 std::vector 更改每个数组并以这种方式初始化它们:
std::vector<double> meanTimeAO = { 0.4437, 0.441, 0.44206, 0.44632, 0.4508, 0.45425,...}
但是现在更改所有数组后,当我尝试编译编译器并因堆栈溢出而崩溃时,我以为我通过将数组更改为 vector 来从堆栈中释放内存空间,但似乎我得到了相反的结果,这是为什么呢??
我应该如何处理这些大数组? (它们是固定的,永远不会改变值或大小)
最佳答案
正如@Ajay 的回答和@Cornstalks 评论正确指出的那样,您可以通过在数组上使用 static 或 constexpr 限定符来完全避免堆栈和堆
const static std::array<float, 1000000> a1 = {}; // OK
constexpr std::array<float, 1000000> a2 = {}; // OK in C++11 onwards
这会将数组存储在内存的数据初始化部分 (good explanation here)。 const 仅用于禁止修改 a1,不需要避免堆栈溢出。声明为 constexpr 的变量也自动为 const,因此不需要限定符。
注意:您也可以通过将数组设置为全局变量来实现 static 的效果,尽管我不推荐这样做。
如果你的数据是非静态的,当元素数量非常大时,你应该使用 std::vector(或其他类型的堆分配内存)。
std::array<float, 1000000> a = {}; // Causes stack-overflow on 32-bit MSVS 2015
std::vector<float> v(1000000); // OK
这是因为默认堆栈大小为 ~1MB,而 100 万个 float 需要 ~4MB。堆的大小受系统可用内存 (RAM) 的限制。 More on the stack and heap here .
std::vector 的缺点是它比 std::array 慢一点(堆内存分配、释放和访问都比堆栈),并且它不是固定大小。但是,您可以将 std::vector 声明为 const 以防止自己(或其他人)意外更改其大小或元素。
const std::vector<float> v = {...};
现在你的 std::vector 导致堆栈溢出的原因有点神秘。然而,当 std::vector 在堆上分配其元素时,它也在堆栈上分配了一个指针(32 位为 4 字节,64 位为 8 字节)。因此,如果您同时在范围内有超过 ~250,000 个 std::vectors,这也会导致堆栈溢出(或在 64 位系统上约为 125,000 个)。
编译器像任何程序一样分配内存——其中一些将在堆栈上。 MSVC 上编译器堆栈溢出的官方错误是 Fatal Error C1063 .
鉴于您的调试器行为异常,我的建议是尝试通过手动将代码拆分为模块化单元并单独编译它们来隔离有问题的代码。通过消耗大量堆栈,例如少量代码可能会导致错误。通过递归生成大量函数。
或者,您的代码可能天生就很复杂,以至于它自然需要比堆栈更多的内存。在这种情况下,拆分代码仍然会有好处,但您也可以尝试 increasing the default stack size of MSVC .
要改进您的代码,您可以尝试将数据拆分为多个 block 。例如,您可以:读取约 256 KB 的数组,对其进行处理,将数组写回文件,然后移动到下一个 256 KB。您可以进一步选择 block 的大小,使其小于 L1 缓存的大小(这样它就可以一次存储),这将通过最大限度地减少缓存未命中来提高性能。
MSVS 2015(更新 2)在编译时产生内部编译器错误
#include "stdafx.h"
#include <array>
int main()
{
constexpr std::array<int, 1000000> a = {};
return 0;
}
static const 变体工作正常,如果我将 a 移到 main 之外(使其成为全局变量),那么它也可以正常工作。
没有 chkstk.asm 是不寻常的。我的位于
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\crt\src\i386\chkstk.asm。如果您错过了它,那么可以尝试重新安装 MS Visual Studio。
关于c++ - 大型数组、std::vector 和堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37427967/
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']