不知道是什么导致了此“分段错误”错误

时间:2020-11-10 21:08:16

标签: c++ segmentation-fault artificial-intelligence

我目前正在为我的AI课模拟自动驾驶汽车。汽车的构造函数将板子作为参数接收,因此它可以设置汽车的位置将第一个节点添加到搜索树,从而可以从中搜索最佳路径。从起始位置到结束位置。问题是,电路板生成时没有任何问题,但是当我尝试将其传递给汽车的构造函数时,会导致Segmentation fault (core dumped)错误。

我使用了调试器(gdb),在其中运行代码并进行了追溯。问题出在这里:

void node_c::add_child(node_c* chld)
{   int i;

    for (i = 0; i < MAX_CHILDREN; i++)
    {   if (children_[i] == NULL)   //This line's the problem
            break;
    }

    if (children_[i] != NULL)
    {   cout << endl << "You can't add any more children." << endl;

        return;
    }

    else children_[i] = chld;
}

注意:'children_'最多包含search_tree节点的4个子级,并且是我必须创建的自定义vector_c类。

这是失败的运算符及其调用的功能

template <typename TDato>
TDato& vector_c<TDato>::operator [](int position) { return get_data(position); }

template <typename TDato>
TDato& vector_c<TDato>::get_data(int a) const { return data_[a]; }

我认为在比较if (children_[i] == NULL)中可能是类型错误,所以我做了一个自定义运算符,它返回了一个对象(TDato),而不是对一个对象(TDato&)的引用,但是它不起作用

我无法想象是什么原因造成的和/或如何解决。

谢谢。

编辑1:这是项目的google drive link,因为即使是最小的可重现示例也太大了,难以在Stack Overflow问题中阅读。我保证它不是很大(小于1 MB)。

编辑2:,这是我能做的最大的事情,以使可重现的示例最小化,因为未包含该示例而使该问题告终。

main.cpp

#include "../include/board_s.hpp"
#include "../include/car_c.hpp"

using namespace std;

int main(void)
{   board_s<int> board(20, 20);

    board.file_depiction();

    car_c car(board);

    board.write(cout);

    return 0;
}

在这里,问题出现在调用car_c的构造函数时。它应该创建一个car_c对象。

board_c.hpp

#ifndef __BOARD_S__
#define __BOARD_S__ 

#include <cstdio>
#include <iostream>
#include <cstring>
#include <random>
#include <fstream>
#include <utility>

#include "matrix_c.hpp"
#include "tree_c.hpp"

using namespace std;

template <typename TDato = int>
class board_s: public matrix_c<TDato>
{  private:
        pair<int, int> starting_pos;
        pair<int, int> finishing_pos;
        
   public:
        board_s(int, int);

        ~board_s(void);

        pair<int, int> get_start(void);

        void file_depiction(void);             //Generates obstacles and starting/finishing points as depicted in board_depiction.txt.

        virtual ostream& write(ostream&);

        int distance(pair<int, int>&) const;   //Returns the distance from a given position to the finishing point

   private:
        bool object_setter(string, int&, int&);

        int object_identifier(string&) const;   //Given the name of the object ("NEW OBSTACLE" [1], "STARTING POSITION" [2] or "FINISHING POSITION" [3]) returns it's code
};

template class board_s<int>;

#endif

board_c.cpp

#include "../include/board_s.hpp"
#include "matrix_c.cpp"

using namespace std;

//The constructor fills the board with empty boxes.
template <typename TDato>
board_s<TDato>::board_s(int m, int n):
matrix_c<TDato>::matrix_c(m + 2, n + 2)
{   for(int i = 1; i < m; i++)
        for(int j = 1; j < n; j++)
            matrix_c<TDato>::at(i, j) = 0;

    for(int i = 0; i < n + 2; i++)
    {   matrix_c<TDato>::at(0, i) = 1;

        matrix_c<TDato>::at(m + 1, i) = 1;
    }

    for(int i = 0; i < m + 2; i++)
    {   matrix_c<TDato>::at(i, 0) = 1;

        matrix_c<TDato>::at(i, n + 1) = 1;
    }

    starting_pos.first = 0;
    starting_pos.second = 0;

    finishing_pos.first = 0;
    finishing_pos.second = 0;
}


template <typename TDato>
board_s<TDato>::~board_s(void){}


template <typename TDato>
pair<int, int> board_s<TDato>::get_start(void) { return starting_pos; }


template <typename TDato>
void board_s<TDato>::file_depiction(void)
{   string line;
    int x, y, i;

    std::ifstream bd;
    bd.open("board_depiction.txt");

    if (bd.is_open())
    {   getline(bd, line);
        getline(bd, line);

        i = line.size() - 1;
        y = matrix_c<TDato>::strtoi(line, i);
        i--;
        x = matrix_c<TDato>::strtoi(line, i);

        matrix_c<TDato>::resize(x + 2, y + 2);
        
        getline(bd, line);
        getline(bd, line);

        i = line.size() - 1;
        y = matrix_c<TDato>::strtoi(line, i);
        i--;
        x = matrix_c<TDato>::strtoi(line, i);

        object_setter("STARTING POSITION", x, y);

        getline(bd, line);
        getline(bd, line);

        i = line.size() - 1;
        y = matrix_c<TDato>::strtoi(line, i);
        i--;
        x = matrix_c<TDato>::strtoi(line, i);

        object_setter("FINISHING POSITION", x, y);

        while (getline(bd, line))
            if (line[0] != 'O')
            {   i = line.size() - 1;
                y = matrix_c<TDato>::strtoi(line, i);
                i--;
                x = matrix_c<TDato>::strtoi(line, i);


                object_setter("NEW OBSTACLE", x, y);
            }
    }

    else cout << "ERROR";
}


template <typename TDato>
ostream& board_s<TDato>::write(ostream& os)
{   int temp = matrix_c<TDato>::get_n() - 2 + (4 * (matrix_c<TDato>::get_n() - 2));
    
    os << " ";

    for (int i = 1; i < temp; i++)
        os << "_";
    
    os << " " << endl << "|";
    
    for (int i = 1; i < matrix_c<TDato>::get_m() - 1; i++)
    {   for (int j = 0; j < 2; j++)
        {   for (int k = 1; k < matrix_c<TDato>::get_n() - 1; k++)
                switch (matrix_c<TDato>::at(i, k))
                {   case 1:
                        os << "████|";
                    break;

                    case 2:
                        if (j == 0)
                            os << " CC |";
                        
                        else os << "_CC_|";
                    break;

                    case 3:
                        if (j == 0)
                            os << " FF |";
                        
                        else os << "_FF_|";
                    break;

                    default:
                        if (j == 0)
                            os << "    |";
                        
                        else os << "____|";
                }

            os << endl;

            if (j == 0) os << "|";
        }

        if (i < matrix_c<TDato>::get_m() - 2) os << "|";     
    }

    os << endl;

    return os;
}


template <typename TDato>
int board_s<TDato>::distance(pair<int, int>& pos) const
{   int d = (finishing_pos.first - pos.first) + (finishing_pos.second - pos.second);

    if (d < 0) return (d * (-1));

    else return d;
}


template <typename TDato>
bool board_s<TDato>::object_setter(string name, int &x, int &y)
{   if((x > 0) && (x < matrix_c<TDato>::get_m() - 1) && (y > 0) && (y < matrix_c<TDato>::get_n() - 1) && (matrix_c<TDato>::at(x, y) == 0))
    {   matrix_c<TDato>::at(x, y) = object_identifier(name);

        cout << endl << endl << "The " << name << " has been set in (" << x << ", " << y << ")" << endl;

        if (name == "STARTING POSITION")
        {   starting_pos.first = x;
            starting_pos.second = y;
        }

        else if (name == "FINISHING POSITION")
        {   finishing_pos.first = x;
            finishing_pos.second = y;
        }

        return true;
    }

    else
    {   cout << endl << "The coordinates that you intriduced were out of reach or the position wasn't free." << endl;

        return false;
    }
}


template <typename TDato>
int board_s<TDato>::object_identifier(string &name) const
{   if (name == "NEW OBSTACLE")
        return 1;

    else if (name == "STARTING POSITION")
        return 2;

    else if (name == "FINISHING POSITION")
        return 3;

    else return 0;

}

matrix_c.hpp

#ifndef __MATRIX_C__
#define __MATRIX_C__ 

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <cstring>

#include "vector_c.hpp"

using namespace std;

template <typename TDato>
class matrix_c  //Template matrix class implemented with a vector.
{   private:
        int m_;
        int n_;
        
        vector_c<TDato> v_;
        
    public:
        matrix_c(void);                                 //Empty constructor

        matrix_c(int, int);                             //Constructor with dimensions

        ~matrix_c(void);

        void resize(int, int);

        TDato& at (int, int);                     //Redirects to position (x, y)

        virtual TDato& operator()(int, int);      //Operator for at(int, int)

        int get_m(void) const;

        int get_n(void) const;

    private:
        int pos(int, int);

    protected:
        int ctoi(char&) const;

        int strtoi(string&, int&) const;
};

#endif

matrix_c.cpp

#include "../include/matrix_c.hpp"

using namespace std;

template <typename TDato>
matrix_c<TDato>::matrix_c(void):
m_(0),
n_(0),
v_() {}


template <typename TDato>
matrix_c<TDato>::matrix_c(int m, int n):
m_(m),
n_(n),
v_(m * n) {}


template <typename TDato>
matrix_c<TDato>::~matrix_c(void) {}


template <typename TDato>
void matrix_c<TDato>::resize(int m, int n)
{   v_.resize(m * n);
    m_ = m;
    n_ = n;
}


template <typename TDato>
TDato& matrix_c<TDato>::at(int i, int j) { return v_[(pos(i,j))]; }


template <typename TDato>
TDato& matrix_c<TDato>::operator()(int i, int j) { return at(i,j); }


template <typename TDato>
int matrix_c<TDato>::get_m(void) const { return m_; }


template <typename TDato>
int matrix_c<TDato>::get_n(void) const { return n_; }


template <typename TDato>
int matrix_c<TDato>::pos(int i, int j) { return ((n_ * i) + j); }


template <typename TDato>
int matrix_c<TDato>::ctoi(char &c) const
{   int n = c;

    return n - 48;
}


template <typename TDato>
int matrix_c<TDato>::strtoi(string &s, int& i) const
{   int n = 0;
    int mult = 1;

    while ((s[i] != ' ') && (i >= 0))
    {   n += ctoi(s[i]) * mult;

        mult *= 10;
        i--;
    }

    return n;
}

template class matrix_c<int>;

vector_c.hpp

#ifndef __VECTOR_C__
#define __VECTOR_C__

#include <iostream>
#include <cstdio>
#include <cassert>

using namespace std;

template <typename TDato>
class vector_c
{   private:
        int sz_;

        TDato* data_;

    public:
        vector_c(void);                     //Empty constructor

        vector_c(int);                      //Constructor with size

        ~vector_c(void);

        TDato& get_data(int) const;

        void set_data(TDato&, int);

        ostream& write(ostream&) const;

        TDato& operator [](int);

        void resize(int);

    private:
        void new_vector(void);

        void del_vector(void);
};

#endif

vector_c.cpp

#include "../include/vector_c.hpp"
#include "../include/node_c.hpp"

using namespace std;

template <typename TDato>
vector_c<TDato>::vector_c(void):
    sz_(0),
    data_(NULL) {}


template <typename TDato>
vector_c<TDato>::vector_c(int size):
    sz_(size),
    data_(new TDato[sz_]) {}


template <typename TDato>
vector_c<TDato>::~vector_c(void)
{   delete[] data_;

    data_ = NULL;
}


template <typename TDato>
TDato& vector_c<TDato>::get_data(int a) const { return data_[a]; }


template <typename TDato>
void vector_c<TDato>::set_data(TDato& dat, int a) { data_[a] = dat;}


template <typename TDato>
TDato& vector_c<TDato>::operator [](int position) { return get_data(position); }


template <typename TDato>
void vector_c<TDato>::resize(int sz)
{   del_vector();
    sz_ = sz;
    new_vector();
}


template <typename TDato>
void vector_c<TDato>::new_vector(void){
    data_ = new TDato[sz_];
}


template <typename TDato>
void vector_c<TDato>::del_vector(void)
{   if (data_ != NULL){
        delete [] data_;
        data_ = NULL;
    }
}


template class vector_c<int>;
template class vector_c<node_c*>;

node_c.hpp

#define MAX_CHILDREN 4

#ifndef __NODE_C__
#define __NODE_C__

#include <iostream>
#include <cstdio>
#include <cassert>

#include "vector_c.hpp"

using namespace std;

class node_c
{   private:
        node_c* parent_;
        
        vector_c< node_c* > children_;

        pair<pair<int, int>, int> data_;
        
    public:
        node_c(void);

        node_c(int &x, int &y, int &cost);

        node_c(pair<pair<int, int>, int>&);

        ~node_c(void);

        void add_child(node_c*);
};

#endif

node_c.cpp

#include "../include/node_c.hpp"

using namespace std;

node_c::node_c(void):
parent_(NULL)
{   for (int i = 0; i < MAX_CHILDREN; i++)
        children_[i] = NULL;

    data_.first.first = 0;
    data_.first.second = 0;

    data_.second = 0;
}


node_c::node_c(int &x, int &y, int &cost):
parent_(NULL)
{   for (int i = 0; i < MAX_CHILDREN; i++)
        children_[i] = NULL;
    
    data_.first.first = x;
    data_.first.second = y;

    data_.second = cost;
}


node_c::node_c(pair<pair<int, int>, int> &dat):
parent_(NULL),
data_(dat)
{   for (int i = 0; i < MAX_CHILDREN; i++)
        children_[i] = NULL;
}


node_c::~node_c(void)
{   parent_ = NULL;

    for (int i = 0; i < MAX_CHILDREN; i++)
        children_[i] = NULL;

    data_.first.first = 0;
    data_.first.second = 0;

    data_.second = 0;
}


void node_c::add_child(node_c* chld)
{   int i;

    for (i = 0; i < MAX_CHILDREN; i++)
    {   if (children_[i] == NULL)
            break;
    }

    if (children_[i] != NULL)
    {   cout << endl << "You can't add any more children." << endl;

        return;
    }

    else children_[i] = chld;
}

tree_c.hpp

#ifndef __TREE_C__
#define __TREE_C__ 

#include "node_c.hpp"

using namespace std;

class tree_c
{  private:
        node_c* root_;

        int depth_;
        
   public:
        tree_c(void);

        tree_c(node_c*);

        node_c* add_node(node_c*, int&, int&, int);
};

#endif

tree_c.cpp

#include "../include/tree_c.hpp"

using namespace std;

tree_c::tree_c(void):
root_(NULL),
depth_(0) {}


tree_c::tree_c(node_c* root):
root_(root),
depth_(1) {}


node_c* tree_c::add_node(node_c* parent, int& x, int& y, int cost)
{   node_c* node = new node_c(x, y, cost);

    parent->add_child(node);
}

car_c.hpp

#ifndef __CAR_C__
#define __CAR_C__

#include <iostream>
#include <cstdio>
#include <cassert>

#include "tree_c.hpp"
#include "board_s.hpp"

using namespace std;

class car_c
{   private:
        tree_c tree_;

        pair<int, int> pos_;

        matrix_c<int> visited_;

    public:
        car_c(void);
        
        car_c(board_s<int>&);

        ~car_c(void);
};

#endif

car_c.cpp

#include "../include/car_c.hpp"

using namespace std;


car_c::car_c(void):
tree_(NULL)
{   pos_.first = 0;
    pos_.second = 0;
}


car_c::car_c(board_s<int>& board):
pos_(board.get_start()),
tree_(tree_.add_node(NULL, pos_.first, pos_.second, 0))
{ visited_(pos_.first, pos_.second) = 1; }


car_c::~car_c(void) {}

调试信息:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401cc2 in node_c::node_c (this=0x6187d0, x=@0x7ffffffeddf0: 8, y=@0x7ffffffeddf4: 0, 
    cost=@0x7ffffffedd2c: 0) at src/node_c.cpp:20
20              children_[i] = NULL;
(gdb) bt
#0  0x0000000000401cc2 in node_c::node_c (this=0x6187d0, x=@0x7ffffffeddf0: 8, y=@0x7ffffffeddf4: 0, 
    cost=@0x7ffffffedd2c: 0) at src/node_c.cpp:20
#1  0x0000000000402007 in tree_c::add_node (this=0x7ffffffedde0, parent=0x0, x=@0x7ffffffeddf0: 8, 
    y=@0x7ffffffeddf4: 0, cost=0) at src/tree_c.cpp:16
#2  0x0000000000402df6 in car_c::car_c (this=0x7ffffffedde0, board=...) at src/car_c.cpp:15
#3  0x0000000000401403 in main () at src/main.cpp:11

很抱歉,我的提问时间太长了,但这是我能做的最小的可复制示例。如果您知道重新创建错误的另一种方法,请告诉我,以便我进行改进。

0 个答案:

没有答案