zoukankan      html  css  js  c++  java
  • [C++]VS2015用array申请50万int类型数组,程序报栈空间溢出

    背景

    最近,想再深入探究一下C++STL中各种容器的性能.
    就尝试用其中的array、vector等容器,申请50万个int的容器空间,再测试其sort()和find()等函数执行时长。
    结果在测试array时,编译能成功,但程序在调试器中执行就报了如下的错误:

    0x00A82519 处有未经处理的异常(在 test_array.exe 中): 0xC00000FD: Stack overflow (参数: 0x00000000, 0x00312000)。
    

    测试源码

    #include <time.h>
    #include <array>
    #include <iostream>
    using namespace std;
    
    #define ASIZE 500000
    
    int main(int argc, char** argv)
    {
    	clock_t timeStart = clock();
    	array<int, ASIZE> nums;
    	for (size_t i = 0; i < ASIZE; i++)
    	{
    		nums[i] = rand();
    	}
    	cout << "milli-seconds: " << (int)(clock() - timeStart) << endl;
    	return 0;
    }
    

    原因分析

    搜了一下就知道是栈空间溢出。
    在尝试了vector后,就更奇怪为什么vector不会造成栈空间溢出,而单单array就会。
    最后查了一下两者源码,vector的空间默认是经stl的空间配置器从堆中申请的,这里就不贴vector的源码了。
    回来看array,其实源码摘取下面一段:

    /* test_array.cpp */
    array<int, ASIZE> nums;
    
    /* array */
    ...
    template<class _Ty,size_t _Size>
    	class array
    	{	// fixed size array of values
    public:
    	typedef array<_Ty, _Size> _Myt;
    ...
    

    在test_array.cpp中array<int, ASIZE> nums; 当array<int, ASIZE>传递给模板类array后,array<int, ASIZE>被typedef定义成一种新的类型_Myt,再用_Myt定义nums;
    在此可以把array<int, ASIZE> nums 理解成 int nums[ASIZE]; 这时就可以知道nums就是一个临时变量了,对于临时变量我们都知道它会被编译器放置到栈空间的。
    如此,从栈空间中申请50万个int类型的内存,已超出程序栈空间大小,造成溢出。

    解决方法

    查看一下VS项目的属性,在链接器--系统,有一个参数项:堆栈保留大小;其默认值为1M(1024*1024=1048576)

    此项的默认值不行,我直接加一倍:

    程序终于可以正常运行了。

    cmake的设置方法

    因为本人基本上都在使用cmake进行工程构建,故此处也分享一下cmake的设置方法,CMakeLists.txt如下

    cmake_minimum_required(VERSION 3.0)
    
    project(test_array)
    
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:2097152")
    
    FILE(GLOB SRC *.cpp *.h)
    
    add_executable(${PROJECT_NAME} ${SRC})
    

    其中的关键在于给链接器添加参数 /STACK:XXXXX

  • 相关阅读:
    Ext2.0布局类初探
    从DHTML、HTC、XHTML到AJAX
    我常用的一些ASP自定义函数
    Javascript的调试利器:Firebug使用详解
    ODBC的多线程应用
    召唤有丰富IOCP实践经验的同行
    欢迎
    关于.NET安装时的dotNETFXRedist_x86.msm
    所谓设计模式
    VC编程经验汇总(一)
  • 原文地址:https://www.cnblogs.com/dilex/p/14965308.html
Copyright © 2011-2022 走看看