2016-07-25 12 views
1

Ich habe die folgende Klasse.SIGSEGV auf Klasse Destruktor

Rubrik:

#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 

cav:

#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; 
    for (int yy=y-1;yy<=y+1;++yy) { 
     for (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; 

    for (auto i = ril_begin; i != 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"; 

     for (int j=x; j<x+amount;++j) { 
      g->setCell(j, y, alive); 
     } 
     x += amount; 

     if (ril_match[4] == "$") { 
      y += 1; 
      x = 0; 
     } 
    } 

    return g; 
} 

Wenn ich erstellen die Klasse mit x=213, y=142 und ril und das Objekt zerstören, das Programm abstürzt:

std::shared_ptr<Generation> g(Generation::parseRil(x, y, ril)); 
g.reset(); 

I Verwenden Sie den Standarddestruktor, keinen benutzerdefinierten Code. Es scheint in parseRil etwas schief geht, da das Erstellen und Zerstören des Objekts mit dem Konstruktor gut funktioniert.

Der Stapel:

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff6b6fe36 in _int_free() from /usr/lib/libc.so.6 
(gdb) bt 
#0 0x00007ffff6b6fe36 in _int_free() from /usr/lib/libc.so.6 
#1 0x000000000046175e in __gnu_cxx::new_allocator<int>::deallocate (this=0x6dd800, __p=0x6f3410) 
    at /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) at /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) at /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>) at /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>) at /usr/include/c++/6.1.1/bits/stl_vector.h:427 
#6 0x000000000046181b in std::_Destroy<std::vector<int, std::allocator<int> > > (__pointer=0x6dd800) 
    at /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) at /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) at /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) at /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>) 
    at /usr/include/c++/6.1.1/bits/stl_vector.h:426 
#11 0x000000000045c8f0 in Generation::~Generation (this=0x6bc630, __in_chrg=<optimized out>) 
    at /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) at /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) 
    at /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>) at /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>) at /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>) at /usr/include/c++/6.1.1/bits/shared_ptr_base.h:1025 
---Type <return> to continue, or q <return> to quit--- 
#17 0x0000000000485107 in init_game() at /home/amProgram received signal SIGSEGV, Segmentation fault. 
0x00007ffff6b6fe36 in _int_free() from /usr/lib/libc.so.6 
(gdb) bt 
#0 0x00007ffff6b6fe36 in _int_free() from /usr/lib/libc.so.6 
#1 0x000000000046175e in __gnu_cxx::new_allocator<int>::deallocate (this=0x6dd800, __p=0x6f3410) 
    at /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) at /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) at /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>) at /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>) at /usr/include/c++/6.1.1/bits/stl_vector.h:427 
#6 0x000000000046181b in std::_Destroy<std::vector<int, std::allocator<int> > > (__pointer=0x6dd800) 
    at /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) at /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) at /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) at /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>) 
    at /usr/include/c++/6.1.1/bits/stl_vector.h:426 
#11 0x000000000045c8f0 in Generation::~Generation (this=0x6bc630, __in_chrg=<optimized out>) 
    at /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) at /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) 
    at /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>) at /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>) at /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>) at /usr/include/c++/6.1.1/bits/shared_ptr_base.h:1025 
---Type <return> to continue, or q <return> to quit--- 
#17 0x0000000000485107 in init_game() at /home/amu/Code/github/GoMtL/src/main.cpp:65 
#18 0x0000000000485577 in main (argc=1, argv=0x7fffffffe928) 
    at /home/amu/Code/github/GoMtL/src/main.cpp:118 

Allerdings, wenn ich klein x und y wählen, wie 18 und 12, das Programm funktioniert ganz gut. Was ist das Problem hier?

Danke!

+1

Sie haben den interessantesten Teil vergessen: 'Generation' Destructor-Code. – TerraPass

+0

... und ich glaube nicht, dass der Konstruktor * tatsächlich * tut, was Sie * denken * es tut! ## Ich versichere dir, "kleines X und Y" ist ein * Hering. * –

+0

@TerraPass: Ich habe keinen Destruktor-Code. Es ist der Standard. – amuttsch

Antwort

0

Okay, ich hatte mehrere Probleme mit dem Code. Erstens hat setCell die Grenzen nicht überprüft, die verletzt wurden. Eine einfache if (x > _x || y > _y) Rückgabe behebt das Problem. (Danke @ascotan)

Aber warum hatten wir Probleme außerhalb der Grenzen? Es stellt sich heraus, dass der ril-Parameter Zeilenumbrüche enthält \r. Dies führte zu einer Fehlfunktion der Regex und erkannte einige neue Zeilen $ Zeichen nicht, wenn sie die erste Zeile nach einer neuen Zeile sind. Das hat x zum Überlaufen gebracht. Nachdem sie entfernt wurden, ist der Out-of-Bound-Zustand nicht mehr aufgetreten und das Programm stürzt nicht mehr ab.