Die*_*ava 16 c++ arrays stack vector c++11
我有一个从大型数组中读取数据的程序,我最初在Visual Studio中将程序划分为两个独立的项目,每个项目分别工作正常,但是当我尝试将它们组合在一起时,程序在调试时滑动了一些步骤.我对C++很新,所以我开始做一些研究,我发现也许我正在用那些巨大的数组填充堆栈,我应该尝试将它们放在堆上.
我决定更改每个数组std::vector并以这种方式初始化它们:
std::vector<double> meanTimeAO = { 0.4437, 0.441, 0.44206, 0.44632, 0.4508, 0.45425,...}
但是当我尝试编译编译器崩溃堆栈溢出后现在更改所有数组后,我以为我通过将数组更改为向量来释放堆栈中的内存空间但是看起来我有相反的结果,为什么呢??
我该如何处理这些大数组呢?(它们是固定不变的值或大小)
如果数组具有固定大小,并且其元素不会更改,则无需使用vector.你可以使用std::array,数组const或constexpr代替.
constexpr float meanTimeAO[] = { 0.4437f, 0.441f, 0.44206f, 0.44632f, 0.4508f, 0.45425f,...}
正如@ Ajay的回答和@Cornstalks评论正确指出你可以通过在数组上使用static或constexpr限定符完全避免堆栈和堆
const static std::array<float, 1000000> a1 = {}; // OK
constexpr    std::array<float, 1000000> a2 = {}; // OK in C++11 onwards
这会将数组存储在内存的数据初始化部分(这里有很好的解释).该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万个浮点数需要大约4MB.堆的大小受系统可用内存(RAM)的限制.更多关于堆栈和堆的信息.
缺点std::vector是它比它慢一点std::array(堆内存分配,释放和访问都比堆栈慢),并且它不是固定大小.但是,您可以声明自己std::vector是const为了防止自己(或其他人)意外地改变其大小或元素.
const std::vector<float> v = {...}; 
现在,为什么你的std::vectors导致堆栈溢出有点神秘.但是std::vector,在堆上分配其元素时,它还会在堆栈上分配指针(32位上为4字节,64位上为8字节).因此,如果同时std::vector在范围内超过〜250,000 s,这也会导致堆栈溢出(或64位系统上的~125,000).
与任何程序一样,编译器会分配内存 - 其中一些将在堆栈中.MSVC上编译器堆栈溢出的官方错误是致命错误C1063.
鉴于您的调试器表现得很奇怪,我的建议是尝试通过手动将代码拆分为模块化单元并单独编译来隔离有问题的代码.通过吞噬大量堆栈(例如通过递归生成大量函数),可能有少量代码可能导致错误.
或者,可能是您的代码本质上非常复杂,自然需要比堆栈更多的内存.在这种情况下,拆分代码仍然有用,但您也可以尝试增加MSVC的默认堆栈大小.
要改进代码,您可以尝试将数据拆分为块.例如,你可以:读入大约256 KB的数组,处理它,将数组写回文件,然后转到下一个256 KB.您可以进一步选择块的大小小于L1缓存的大小(因此它可以一次存储),这将通过最小化缓存未命中来提高性能.
MSVS 2015(更新2)在编译时产生内部编译器错误
#include "stdafx.h"
#include <array>
int main()
{
     constexpr std::array<int, 1000000> a = {};
     return 0;
}
该static const变种工作得很好,如果我移动a之外主要的(使其成为一个全局变量),那么它也能正常工作.    
没有chkstk.asm是不寻常的.我的位于 
 C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\crt\src\i386\chkstk.asm.如果您错过了,那么可以尝试重新安装MS Visual Studio.