我有以下课程。
部首:
#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=213
,y=142
和ril创建课程并破坏对象时,程序崩溃了:
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时,程序运行得很好。这有什么问题?
谢谢!
答案 0 :(得分:0)
好的,我的代码存在多个问题。首先,setCell
没有检查违反的界限。一个简单的if (x > _x || y > _y)
返回修复了问题。 (谢谢@ascotan)
但为什么我们有超出范围的问题?事实证明,ril参数中包含换行符\r
。这导致正则表达式出现故障,并且如果它们是新行之后的第一个字符,则不会识别一些新的行$
字符。这导致x
溢出。删除它们后,再次发生了越界条件,程序不再崩溃。