【问题标题】:Segfault error when calling a method through pointer通过指针调用方法时出现段错误
【发布时间】:2013-08-28 06:03:08
【问题描述】:

我有一个名为 gridObject 的基类

这是头文件:

#ifndef ITEM_H
#define ITEM_H

class gridObject
{
public:
    gridObject();
    virtual ~gridObject();

    virtual int get_GridID() = 0;

    virtual int get_x() = 0;
    virtual int get_y() = 0;

    virtual int get_direction() = 0;

    void set_x(int x);
    void set_y(int y);

    void set_direction(unsigned int direction);

protected:
private:
    int _x;
    int _y;

    unsigned int _direction;
};

#endif // ITEM_H

我有一个叫做 player 的子类

这是类文件中的 get_GridID() 方法:

int player::get_GridID() { return 2; }

还有一个网格类,它通过二维向量跟踪其上的所有对象。在头文件中,有那个向量:

private:
    vector<vector<gridObject*> > _position;

以下是分别在特定位置设置和获取对象的方法:

void grid::setGridPosition(int x, int y, gridObject* obj) { _position[y][x] = obj; }
gridObject* grid::getGridPosition(int x, int y) { return _position[y][x]; }

我遇到的问题在这里:

int main()
{
    grid * gr = new grid(10, 10);

    player p(0, 0, 100);

    gridObject * go = &p;

    gr->setGridPosition(0, 0, go);

    cout << gr->getGridPosition(0, 0)->get_GridID();

    return 0;
}

它在以下位置崩溃:cout getGridPosition(0, 0)->get_GridID();

我已经包含了所有合适的头文件。

编辑:这里是网格的构造函数和_position的初始化:

grid::grid(int width, int length)
{
    setSize(width, length);
}


void grid::setSize(int width, int length)
{
    setLength(length);
    setWidth(width);
}

void grid::setLength(int val) { _position.resize(val); }

void grid::setWidth(int val)
{
    for(unsigned int i = 0; i < _position.size() - 1; i++)
        for(unsigned int j = 0; j < _position.at(i).size() - 1; j++)
           _position.at(i).resize(val);
}

【问题讨论】:

  • 你应该尝试删除所有不相关的代码,并添加相关的代码,这是缺失的。例如,您如何初始化_position?你的构造函数和析构函数是做什么的?
  • 尤其是getGridPosiion()setGridPosition()。请注意,如果您有一个由成员函数触发的故障,那么所述成员应该始终在您发布的代码片段中。
  • 添加了构造函数和初始化
  • 是的,它只是一个嵌套向量。这不会导致索引越界错误吗?
  • 不,如果索引在 [0;向量.size()-1]。但你实际上只是初始化范围 [0; vector.size()-2].

标签: c++ pointers segmentation-fault


【解决方案1】:

您正在使用向量的向量:

vector<vector<gridObject*> > _position;

但您初始化_position 的方式如下:

_position.resize(length);
for(unsigned int i = 0; i < _position.size() - 1; i++)
    for(unsigned int j = 0; j < _position.at(i).size() - 1; j++)
       _position.at(i).resize(width);

请注意,第一个 resize 构造 length 类型为 vector&lt;gridObject*&gt; 的对象。然后,您不是通过这些新构建的向量进行迭代,而是通过它们的元素(第二个嵌套循环)进行迭代,在这种情况下,这会导致行 _position.at(i).resize(width); 永远不会执行,因此 _position[y][x] = obj 尝试访问导致 未定义的行为,您将其视为分段错误。

试试这个(grid::setSize):

_position.resize(length);
for(unsigned int i = 0; i < _position.size() - 1; ++i)
    _position[i].resize(width);

还可以考虑使用typedefstd::vector&lt;gridObject*&gt; 创建别名:)

【讨论】:

  • 我在 stl_vector.h 中遇到错误:错误:从 'int' 到 'std::vector::value_type {aka gridObject*}'的无效转换 [-fpermissive]
  • @Electrk:嗯,然后尝试在循环内显式调整它的大小。查看我的编辑。
  • 仍然出现段错误 void grid::setSize(int width, int length) { _position.resize(length); for(unsigned int i = 0; i
  • @Electrk:我看不出有任何其他原因会导致出现段错误(在您向我们展示的代码中)。尝试逐步调试您的代码并找到导致它的行(尝试缩小范围...)
  • @Electrk:不。您应该尝试自己定位问题,以便您可以自己解决问题,或者将问题发布为不需要太多代码的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多