【问题标题】:c++ pathfinder - vector of objects with pointersc++ pathfinder - 带有指针的对象向量
【发布时间】:2020-06-27 13:29:55
【问题描述】:

我的析构函数有问题。我有两个课程:地图和瓷砖。它们看起来像这样: (如果下面的代码片段还不够,我将在这个项目中添加 github,其中包含完整的代码: https://github.com/TMalicki/PathFinder-algorithms)

class Tile
{
  private:
  Tile* parent;
  ...
  public:
  Tile(sf::Vector2f size = { 50.f ,50.f });
  Tile(const Tile& cTile);
  Tile& operator=(const Tile& aTile);
  ~Tile();
  ...
}

class Map
{
private:
vector<Tile*> board;
...
public:   
Map(sf::Vector2i numberOfTiles = { 10, 10 }, sf::Vector2f sizeOfTiles = { 
50.f, 50.f });
Map(const Map& cMap);
Map& operator=(const Map& aMap);
~Map();
...
}

它们的析构函数看起来像这样:

Tile::~Tile()
{
    if (parent != nullptr)
    {
        delete parent;
        parent = nullptr;
    }
}

Map::~Map()
{
    for (int i = 0; i < board.size(); i++)
    {
        delete board[i];
        board[i] = nullptr;
    }
}

代码用于最短路径搜索算法。我必须存储以前的 Tile,所以当算法找到完成时,它可以向后搜索最短路径。如果需要,我可以添加更多代码。总结一下:地图对象有瓷砖的矢量。每个 Tile 首先没有指向任何东西。但是如果它被算法使用而不是前一个的确切 Tile 存储位置,依此类推到开始。我知道智能指针可以帮助我,但我认为首先学习如何做到这一点对我有好处,也许更难。 我认为问题在于(我不知道为什么)在使用 Tiles 删除 Map 矢量时,我不仅删除了确切的 Tile,而且还以某种方式删除了该 Tile 的父级 Tile?和 f.e.在下一次迭代中,当它应该删除上一次迭代的父级时,它不能因为它已经被删除。我认为在 Tile 析构函数中的 if 语句之后,如果它已经是,它不会被延迟。但这没有帮助。

我有这样的异常抛出:

从调试器模式我有这个:

  • 第一次迭代

  • 第二次迭代

在从调试器模式进行分析期间,我开始认为精确图块的析构函数首先删除父图块,然后是他自己。之后它跳转到 Tile 析构函数中的 parent = nullptr 行。但不知何故,只有子 Tile 被设置为 nullptr。

【问题讨论】:

  • Map object has vector of Tiles. -- 不,它没有。它的向量是Tile *,而不是Tile。为什么不是简单的vector&lt;Tile&gt;?如果指针在对象之间共享,那么 C++ 中有一个叫做 std::shared_ptr 的东西,而不是使用原始指针。
  • #PaulMcKenzie 是的,我知道智能指针,但我认为它有助于我更好地理解该主题。所以我试图在那个项目中避免使用智能指针。还有......是的,我的意思是Tile*。我使用了Tile*,因为我想从Map类对象更改Tile对象的一些属性。
  • 您正在到处删除Tile *,而没有一个连贯的策略来确定谁是所有者。您将在 Map 析构函数中删除 Tile *,同时也在 Tile 析构函数(父级)中删除 Tile *。谁拥有什么?您不能两次删除相同的内存地址。这正是共享指针解决的问题——如果您知道两个或多个实体将共享一个指针,而最后一个使用它的实体是指向 delete 指针的最后一个,那么这就是 shared_ptr用于。

标签: c++ pointers sfml destructor path-finding


【解决方案1】:

问题可能是 parent 不是拥有指针,因此它不应该删除 parent。

Tile::~Tile() {
    if (parent != nullptr) {
        delete parent; <----------- here
        parent = nullptr;
    }
}

否则当地图删除图块时,它已经被删除了。删除这部分代码应该可以解决问题。

【讨论】:

  • #Surt 你能解释的更详细一点吗?父母不拥有指针是什么意思?但是父母是指针。不知何故,我觉得我知道这是正确的答案,但我不认为我完全理解这一点。我以你的方式修复了它,现在它正在工作,但我仍然会欣赏一些更好的提示,为什么那是错误的。是不是因为Map 类有vector&lt;Tile*&gt;? I'm thinking that in Map` 析构函数我删除了整个Tile,但是Tile 类有指针应该在Tile 类中被销毁...
  • @Tojmak 如果我正确理解了您的代码,则 Map 拥有所有瓦片,Tile 中的父级只是 Map 已经拥有的另一个瓦片。
  • 确实如此。好的......点击了一些东西;d。所以……总结一下。 parent 实际上是 Tile 类的属性。它应该被删除。但是因为它指向另一个 Tile 而不是应该删除所有 Tiles 被删除的地方。所以...在 Map 类中,在那一行 delete board[i]; 中。该行删除 Tile 对象,但在执行 Tile 类的析构函数之前。而我之前所做的是删除另一个 Tile(仍将被 Map 析构函数删除),其父级指向该 Tile。真的吗? ;d
  • @Tojmak 是的,您对 Tiles 进行了双重删除。
猜你喜欢
  • 2011-10-01
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多