简单研究一下c++ vector是否会栈溢出

  • Post author:
  • Post category:其他




使用char数组复现问题

我在linux环境下,简单复现了一下栈溢出的情况。首先使用

ulimit -a | grep stack

得到当前shell下应用程序的栈大小是8192K,也就是8M。在main函数中定义了一个9M空间的char数组。然后编译运行,预期运行时提示段错误。

[root@wxk test]# ulimit -a | grep stack
stack size              (kbytes, -s) 8192
[root@wxk test]# g++ -v
使用内建 specs。
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
目标:x86_64-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
线程模型:posix
gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
[root@wxk test]#
[root@wxk test]# cat test_stack.cpp
#include <vector>
int main() {
    char a[1024 * 1024 * 9] = {0};
    return 0;
}
[root@wxk test]# g++ -std=c++11 test_stack.cpp
[root@wxk test]# ./a.out
段错误
[root@wxk test]#



使用std::vector是否会导致栈溢出

按我之前的理解,使用vector时应该也会导致栈溢出,实际测试却并不是这样。

[root@wxk test]# ulimit -a | grep stack
stack size              (kbytes, -s) 8192
[root@wxk test]# cat test_stack.cpp
#include <vector>
int main() {
    // char a[1024 * 1024 * 9] = {0};
    std::vector<char> a(1024 * 1024 * 9, 0);
    return 0;
}
[root@wxk test]# g++ -std=c++11 test_stack.cpp
[root@wxk test]# ./a.out
[root@wxk test]#

那么如果vector存的不是基础数据类型,而是对象会怎么样,我改了一下代码,再次验证了一下,结果是一样的,不会栈溢出。

[root@wxk test]# ulimit -a | grep stack
stack size              (kbytes, -s) 8192
[root@wxk test]# cat test_stack.cpp
#include <vector>
int main() {
    // char a[1024 * 1024 * 9] = {0};
    // std::vector<char> a(1024 * 1024 * 9, 0);
    struct Info {
        char a[1024 * 1024] = {0};
    };
    std::vector<Info> a(9);
    return 0;
}
[root@wxk test]# g++ -std=c++11 test_stack.cpp
[root@wxk test]# ./a.out
[root@wxk test]#

看了一下std::vector的源码,在我的机器上,源码路径在/usr/include/c++/4.8.5/bits/stl_vector.h,看了源码后发现,vector使用的空间是在堆上分配的,所以不会导致栈溢出。

vector类是从基类_Vector_base继承而来的。

struct _Vector_base {
      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
        rebind<_Tp>::other _Tp_alloc_type;
        
      struct _Vector_impl
      : public _Tp_alloc_type
      {
        pointer _M_start;
        pointer _M_finish;
        pointer _M_end_of_storage;
       };
       
    public:
      _Vector_impl _M_impl;
      
     pointer
      _M_allocate(size_t __n)
      { return __n != 0 ? _M_impl.allocate(__n) : 0; }
      
      _Vector_base(size_t __n)
      : _M_impl()
      { _M_create_storage(__n); }

    private:
      void
      _M_create_storage(size_t __n)
      {
        this->_M_impl._M_start = this->_M_allocate(__n);
        this->_M_impl._M_finish = this->_M_impl._M_start;
        this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
      }
};

class vector : protected _Vector_base<_Tp, _Alloc> {
};

函数调用链入下



版权声明:本文为qq_20892953原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。