Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 大型数组、std::vector和堆栈溢出_C++_Arrays_C++11_Vector_Stack - Fatal编程技术网

C++ 大型数组、std::vector和堆栈溢出

C++ 大型数组、std::vector和堆栈溢出,c++,arrays,c++11,vector,stack,C++,Arrays,C++11,Vector,Stack,我有一个从大数组读取数据的程序,我最初在VisualStudio中将该程序分为两个独立的项目,每个项目都工作得很好,但当我试图将它们放在一起时,该程序在调试时跳过了一些步骤,表现得很滑稽。我在C++上是非常新的,所以我开始做一些研究,我发现我可能是用那些巨大的数组填充堆栈,我应该尝试把它们放到堆上。 我决定更改std::vector的每个数组,并通过以下方式初始化它们: std::vector<double> meanTimeAO = { 0.4437, 0.441, 0.44206

我有一个从大数组读取数据的程序,我最初在VisualStudio中将该程序分为两个独立的项目,每个项目都工作得很好,但当我试图将它们放在一起时,该程序在调试时跳过了一些步骤,表现得很滑稽。我在C++上是非常新的,所以我开始做一些研究,我发现我可能是用那些巨大的数组填充堆栈,我应该尝试把它们放到堆上。 我决定更改
std::vector
的每个数组,并通过以下方式初始化它们:

std::vector<double> meanTimeAO = { 0.4437, 0.441, 0.44206, 0.44632, 0.4508, 0.45425,...}
std::vector meanstimeao={0.4437,0.441,0.44206,0.44632,0.4508,0.45425,}
但是现在当我试图编译编译器时,改变了所有的数组,导致堆栈溢出,我以为我通过改变数组作为向量来释放堆栈中的内存空间,但是我似乎得到了相反的结果,为什么呢


我应该如何处理这些大型阵列?(它们是固定的,永远不会改变值或大小)

如果数组的大小是固定的,并且其元素不变,那么就不需要使用
向量。您可以使用
std::array
、数组of
const
constepr

constexpr float meanTimeAO[] = { 0.4437f, 0.441f, 0.44206f, 0.44632f, 0.4508f, 0.45425f,...}

正如@Ajay的回答和@Cornstalks的评论正确指出的那样,通过在数组上使用
static
constepr
限定符,可以完全避免堆栈和堆

const static std::array<float, 1000000> a1 = {}; // OK
constexpr    std::array<float, 1000000> a2 = {}; // OK in C++11 onwards
这是因为默认堆栈大小为~1MB,100万次浮点运算需要~4MB。堆的大小受系统可用内存(RAM)的限制

std::vector
的缺点是它比
std::array
慢一点(堆内存分配、释放和访问都比堆栈慢),而且它不是固定大小。但是,您可以将您的
std::vector
声明为
const
,以防止您自己(或其他人)意外更改其大小或元素

const std::vector<float> v = {...}; 
static const
变量可以正常工作,如果我将
a
移到main之外(使其成为全局变量),那么它也可以正常工作

  • 没有chkstk.asm是不寻常的。矿山位于
    C:\ProgramFiles(x86)\Microsoft Visual Studio 14.0\VC\crt\src\i386\chkstk.asm
    。如果您丢失了它,那么可以尝试重新安装MS Visual Studio


  • 指出上述答案中可能忽略的几点:

  • “程序在调试时跳过了一些步骤,表现得很滑稽”。OP,你能提供更多关于你的意思的细节吗?也许,您正在调试一个发布版本,当您逐步完成代码时,您会发现正在执行的代码行不是您期望下一个执行的代码行(这对于具有编译器优化的发布版本来说是完全正确的行为)

  • 问题指出编译器因堆栈溢出而崩溃。不是执行的程序。所以问题是编译器的问题。当然,更改代码可能会使编译器不会崩溃,但上面关于在堆栈上分配std::vector的注释与可能导致编译器崩溃的原因无关

  • 建议:您可以尝试查看正在使用的编译器版本中是否存在任何已知错误(即,查看您的编译器供应商是否发布了可能解决编译器崩溃问题的最新版本)


    另外,特别是在“它们的值或大小永远不会改变”的注释中,尝试将数据放入静态常量双数组,而不是std::vectors(甚至是链表)。当您可能只需要使用double[]时,静态分配的只读链表是一种浪费时间的行为。静态常量数据是在编译/链接时而不是运行时初始化的,并且存在于它自己的内存区域中(严格来说,既不是堆栈也不是堆)。

    您是否尝试过让数组只
    静态常量float meanTimeAO[]={0.4437,0.441,0.44206,0.44632,0.4508,0.45425,}
    ?如果你这样做的话,那就不应该把它们放在堆栈上。将带有初始值设定项的数组放在函数解决方案之外,所有数组的大小都是固定的。所有数组都使用称为链表的数据结构,其中每个元素存储一个引用下一个连续元素的对象。或者,通过实例化一个新向量并复制所有元素,您可以始终使用新的大小重新定义向量,但这次使用更大的大小。@MosheRabaev:数组的固定大小不是OP的问题;这是一个不变量。在这里使用链表(甚至是
    std::vector
    )是不必要的,而且会很迂回。我喜欢有人在堆栈溢出上问关于堆栈溢出的问题。我在VS2015本身上也编译了同样的问题,它编译得很好。希望你有RTM。此外,表格本身表示支持
    constexpr
    。谢谢@Ajay!我刚刚用VS2015中的一个新项目测试了您的代码,它运行得非常好。我不知道我以前的项目出了什么问题。抱歉,我的意思是不支持“Extended constexpr”(在“C++14核心语言功能”标题下),但我想我混淆了两者,因为我认为需要C++14将变量声明为constexpr。啊,我发现了错误的根源。当我按原样测试代码时,它工作得非常好。但是它只分配了6个浮动(忽略…)。当我尝试
    constexpr float a[1000000]={}
    constexpr std::数组a={}我得到“发生内部编译器错误”,尽管我不确定原因。对于小尺寸的数组,它可以正常工作。很抱歉,我的错误-我在主函数中初始化了数组。现在我已经将数组移到了主函数之外,它工作得非常好。关于默认堆栈大小:1MB已经有很多堆栈了(windows,对吧?)。我的系统(Linux,BSD)大约有8KB。非常感谢大家的回复。。。让我澄清我提出的第一点。。。当我
    
    const std::vector<float> v = {...}; 
    
    #include "stdafx.h"
    #include <array>
    int main()
    {
         constexpr std::array<int, 1000000> a = {};
         return 0;
    }