c++ - SIGSEGV on class destructor -
i have following class.
header:
#include <iostream> #include <vector> #include <regex> #ifndef generation_h #define generation_h class generation { public: generation(int x, int y); ~generation() { } void setcell(int x, int y, bool alive); bool getcell(int x, int y); int surroundinglivingcells(int x, int y); int getx(); int gety(); static std::shared_ptr<generation> parseril(int x_i, int y_i, const std::string& ril); private: int _x; int _y; std::vector<int> _born = {3}; std::vector<int> _starve = {3, 5}; std::vector<std::vector<int>> _data; }; #endif // generation_h
cpp:
#include <regex> #include "generation.h" generation::generation(int x, int y) : _x(x), _y(y) { _data.resize(y, std::vector<int>(x, 0)); } void generation::setcell(int x, int y, bool alive) { _data[y][x] = alive ? 1 : 0; } bool generation::getcell(int x, int y) { return _data[y][x] == 1; } int generation::surroundinglivingcells(int x, int y) { int c = 0; (int yy=y-1;yy<=y+1;++yy) { (int xx=x-1;xx<=x+1;++xx) { if (xx == x && yy == y) continue; if (xx>=0 && yy>=0 && xx < _x && yy < _y) { c += _data[yy][xx]; } } } return c; } int generation::getx() { return _x; } int generation::gety() { return _y; } std::shared_ptr<generation> generation::parseril(int x_i, int y_i, const std::string& ril) { std::shared_ptr<generation> g(new generation(x_i, y_i)); std::regex ril_regex("((\\d*)(\\w))([!$]*)"); auto ril_begin = std::sregex_iterator(ril.begin(), ril.end(), ril_regex); auto ril_end = std::sregex_iterator(); int x = 0; int y = 0; (auto = ril_begin; != ril_end; ++i) { std::smatch ril_match = *i; int amount = ril_match[2] != "" ? std::stoi(ril_match[1]) : 1; bool alive = ril_match[3] == "o"; (int j=x; j<x+amount;++j) { g->setcell(j, y, alive); } x += amount; if (ril_match[4] == "$") { y += 1; x = 0; } } return g; }
when create class x=213
, y=142
, ril , destruct object, program crashes:
std::shared_ptr<generation> g(generation::parseril(x, y, ril)); g.reset();
i use default destructor, no custom code there. seems in parseril
going wrong, since creating , destructing object contructor works fine.
the stack:
program received signal sigsegv, segmentation fault. 0x00007ffff6b6fe36 in _int_free () /usr/lib/libc.so.6 (gdb) bt #0 0x00007ffff6b6fe36 in _int_free () /usr/lib/libc.so.6 #1 0x000000000046175e in __gnu_cxx::new_allocator<int>::deallocate (this=0x6dd800, __p=0x6f3410) @ /usr/include/c++/6.1.1/ext/new_allocator.h:110 #2 0x00000000004602f7 in std::allocator_traits<std::allocator<int> >::deallocate (__a=..., __p=0x6f3410, __n=213) @ /usr/include/c++/6.1.1/bits/alloc_traits.h:442 #3 0x000000000045eb0a in std::_vector_base<int, std::allocator<int> >::_m_deallocate (this=0x6dd800, __p=0x6f3410, __n=213) @ /usr/include/c++/6.1.1/bits/stl_vector.h:178 #4 0x000000000045da87 in std::_vector_base<int, std::allocator<int> >::~_vector_base (this=0x6dd800, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/stl_vector.h:160 #5 0x000000000045cd35 in std::vector<int, std::allocator<int> >::~vector (this=0x6dd800, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/stl_vector.h:427 #6 0x000000000046181b in std::_destroy<std::vector<int, std::allocator<int> > > (__pointer=0x6dd800) @ /usr/include/c++/6.1.1/bits/stl_construct.h:93 #7 0x00000000004603f5 in std::_destroy_aux<false>::__destroy<std::vector<int, std::allocator<int> >*> ( __first=0x6dd800, __last=0x6ddbc0) @ /usr/include/c++/6.1.1/bits/stl_construct.h:103 #8 0x000000000045ec4a in std::_destroy<std::vector<int, std::allocator<int> >*> (__first=0x6dce70, __last=0x6ddbc0) @ /usr/include/c++/6.1.1/bits/stl_construct.h:126 #9 0x000000000045dc17 in std::_destroy<std::vector<int, std::allocator<int> >*, std::vector<int, std::allocator<int> > > (__first=0x6dce70, __last=0x6ddbc0) @ /usr/include/c++/6.1.1/bits/stl_construct.h:151 #10 0x000000000045cd6d in std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::~vector (this=0x6bc668, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/stl_vector.h:426 #11 0x000000000045c8f0 in generation::~generation (this=0x6bc630, __in_chrg=<optimized out>) @ /home/amu/code/github/gomtl/src/generation.h:10 #12 0x0000000000484bfc in std::_sp_counted_ptr<generation*, (__gnu_cxx::_lock_policy)2>::_m_dispose ( this=0x6bbe50) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:372 #13 0x000000000045dee4 in std::_sp_counted_base<(__gnu_cxx::_lock_policy)2>::_m_release (this=0x6bbe50) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:150 #14 0x000000000045cf67 in std::__shared_count<(__gnu_cxx::_lock_policy)2>::~__shared_count ( this=0x7fffffffe408, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:662 #15 0x000000000045c930 in std::__shared_ptr<generation, (__gnu_cxx::_lock_policy)2>::~__shared_ptr ( this=0x7fffffffe400, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:928 #16 0x0000000000485e55 in std::__shared_ptr<generation, (__gnu_cxx::_lock_policy)2>::reset ( this=0x6a6bb0 <generation_current>) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:1025 ---type <return> continue, or q <return> quit--- #17 0x0000000000485107 in init_game () @ /home/amprogram received signal sigsegv, segmentation fault. 0x00007ffff6b6fe36 in _int_free () /usr/lib/libc.so.6 (gdb) bt #0 0x00007ffff6b6fe36 in _int_free () /usr/lib/libc.so.6 #1 0x000000000046175e in __gnu_cxx::new_allocator<int>::deallocate (this=0x6dd800, __p=0x6f3410) @ /usr/include/c++/6.1.1/ext/new_allocator.h:110 #2 0x00000000004602f7 in std::allocator_traits<std::allocator<int> >::deallocate (__a=..., __p=0x6f3410, __n=213) @ /usr/include/c++/6.1.1/bits/alloc_traits.h:442 #3 0x000000000045eb0a in std::_vector_base<int, std::allocator<int> >::_m_deallocate (this=0x6dd800, __p=0x6f3410, __n=213) @ /usr/include/c++/6.1.1/bits/stl_vector.h:178 #4 0x000000000045da87 in std::_vector_base<int, std::allocator<int> >::~_vector_base (this=0x6dd800, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/stl_vector.h:160 #5 0x000000000045cd35 in std::vector<int, std::allocator<int> >::~vector (this=0x6dd800, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/stl_vector.h:427 #6 0x000000000046181b in std::_destroy<std::vector<int, std::allocator<int> > > (__pointer=0x6dd800) @ /usr/include/c++/6.1.1/bits/stl_construct.h:93 #7 0x00000000004603f5 in std::_destroy_aux<false>::__destroy<std::vector<int, std::allocator<int> >*> ( __first=0x6dd800, __last=0x6ddbc0) @ /usr/include/c++/6.1.1/bits/stl_construct.h:103 #8 0x000000000045ec4a in std::_destroy<std::vector<int, std::allocator<int> >*> (__first=0x6dce70, __last=0x6ddbc0) @ /usr/include/c++/6.1.1/bits/stl_construct.h:126 #9 0x000000000045dc17 in std::_destroy<std::vector<int, std::allocator<int> >*, std::vector<int, std::allocator<int> > > (__first=0x6dce70, __last=0x6ddbc0) @ /usr/include/c++/6.1.1/bits/stl_construct.h:151 #10 0x000000000045cd6d in std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >::~vector (this=0x6bc668, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/stl_vector.h:426 #11 0x000000000045c8f0 in generation::~generation (this=0x6bc630, __in_chrg=<optimized out>) @ /home/amu/code/github/gomtl/src/generation.h:10 #12 0x0000000000484bfc in std::_sp_counted_ptr<generation*, (__gnu_cxx::_lock_policy)2>::_m_dispose ( this=0x6bbe50) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:372 #13 0x000000000045dee4 in std::_sp_counted_base<(__gnu_cxx::_lock_policy)2>::_m_release (this=0x6bbe50) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:150 #14 0x000000000045cf67 in std::__shared_count<(__gnu_cxx::_lock_policy)2>::~__shared_count ( this=0x7fffffffe408, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:662 #15 0x000000000045c930 in std::__shared_ptr<generation, (__gnu_cxx::_lock_policy)2>::~__shared_ptr ( this=0x7fffffffe400, __in_chrg=<optimized out>) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:928 #16 0x0000000000485e55 in std::__shared_ptr<generation, (__gnu_cxx::_lock_policy)2>::reset ( this=0x6a6bb0 <generation_current>) @ /usr/include/c++/6.1.1/bits/shared_ptr_base.h:1025 ---type <return> continue, or q <return> quit--- #17 0x0000000000485107 in init_game () @ /home/amu/code/github/gomtl/src/main.cpp:65 #18 0x0000000000485577 in main (argc=1, argv=0x7fffffffe928) @ /home/amu/code/github/gomtl/src/main.cpp:118
however, when choose small x , y, 18 , 12, program works fine. problem here?
thanks!
okay, had multiple issues code. first, setcell
didn't check bounds, violated. simple if (x > _x || y > _y)
return fixed problem. (thanks @ascotan)
but why did have out of bounds issues? turns out ril parameter had newline characters in \r
. caused regex malfunction , didn't recognize new row $
characters if first 1 after new line. caused x
overflow. after removing them, out of bounds condition didn't occur again , program doesn't crash anymore.
Comments
Post a Comment