关于类析构函数的SIGSEGV

时间:2016-07-25 17:10:30

标签: c++ destructor

我有以下课程。

部首:

#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;
    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;
}

当我使用x=213y=142ril创建课程并破坏对象时,程序崩溃了:

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

我使用默认的析构函数,那里没有自定义代码。似乎在parseRil出现问题,因为使用构造函数创建和销毁对象的工作正常。

筹码:

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

然而,当我选择小的x和y,比如18和12时,程序运行得很好。这有什么问题?

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,我的代码存在多个问题。首先,setCell没有检查违反的界限。一个简单的if (x > _x || y > _y)返回修复了问题。 (谢谢@ascotan)

但为什么我们有超出范围的问题?事实证明,ril参数中包含换行符\r。这导致正则表达式出现故障,并且如果它们是新行之后的第一个字符,则不会识别一些新的行$字符。这导致x溢出。删除它们后,再次发生了越界条件,程序不再崩溃。