C++ 如何在没有内存泄漏的情况下删除对象指针的2D向量?C++;和SFML

C++ 如何在没有内存泄漏的情况下删除对象指针的2D向量?C++;和SFML,c++,pointers,memory-leaks,sfml,2d-vector,C++,Pointers,Memory Leaks,Sfml,2d Vector,我有一个2D向量的平铺指针。每次加载不同的贴图时,我都希望删除向量中的所有平铺,释放内存,然后用不同的平铺重新填充 std::vector<std::vector<Tile*>> map; 问题是,每次我用磁贴重新填充向量时,我的内存都会继续填满,直到游戏崩溃。我的问题是,如何正确地删除向量中的所有内容,从而释放内存 以下是我试图删除没有释放内存的磁贴的尝试: for(int ii = 0; ii < this->map.size(); ii++){

我有一个2D向量的平铺指针。每次加载不同的贴图时,我都希望删除向量中的所有平铺,释放内存,然后用不同的平铺重新填充

std::vector<std::vector<Tile*>> map;
问题是,每次我用磁贴重新填充向量时,我的内存都会继续填满,直到游戏崩溃。我的问题是,如何正确地删除向量中的所有内容,从而释放内存

以下是我试图删除没有释放内存的磁贴的尝试:

for(int ii = 0; ii < this->map.size(); ii++){
    for(int jj = 0; jj < this->h; jj++){

        delete &this->map[ii][jj]->baseSprite;
        delete &this->map[ii][jj]->color;
        delete &this->map[ii][jj]->light_level;
        delete &this->map[ii][jj]->loc_x;
        delete &this->map[ii][jj]->loc_y;
        delete &this->map[ii][jj]->type;

        delete &this->map[ii][jj];
    }
}


map.clear() 
for(intii=0;iimap.size();ii++){
对于(intjj=0;jjh;jj++){
删除&this->map[ii][jj]->baseSprite;
删除&this->map[ii][jj]->color;
删除&this->map[ii][jj]->light\u level;
删除&this->map[ii][jj]->loc\u x;
删除此->映射[ii][jj]->loc_y;
删除&this->map[ii][jj]->type;
删除此->映射[ii][jj];
}
}
map.clear()

如果需要任何额外的代码,请告诉我,谢谢。

平铺
类判断,在向量中使用
平铺
指针而不是直接使用
平铺
似乎很愚蠢。以下是您的问题的可能解决方案:

  • 定义一个复制构造函数,即定义
    Tile::Tile(const Tile&)
    应该做什么(它应该将所有数据成员复制到新构造的Tile)
  • 定义赋值运算符,即定义
    Tile&Tile::operator=(const Tile&)
    应该做什么(它应该调用其所有数据成员上的所有
    operator=
    函数,并
    返回*此
  • 现在乍一看,这似乎还可以,但我查看了
    sf::Sprite
    文档,没有为
    sf::Sprite
    定义复制构造函数或赋值运算符。精灵似乎只能通过
    sf::Texture
    创建。幸运的是,每个
    sf::Sprite
    都公开了一个公共成员函数,该函数返回自己的绑定
    sf::Texture
    。但是,查看
    sf::Sprite::getTexture()
    的文档,它返回一个指向
    sf::Texture
    的指针,如果没有纹理绑定到
    sf::Sprite
    ,该指针可能为
    NULL
    。您应该在复制构造函数和
    Tile
    的赋值运算符中检查这一点

    那么,复制构造函数应该如下所示:

    map[x][y] = tile;
    
    Tile::Tile(const Tile& other)
    : type(other.type)
    , color(other.color)
    , light_level(other.light_level)
    , loc_x(other.loc_x)
    , loc_y(other.loc_y)
    , baseSprite()
    {
        sf::Texture* result = other.baseSprite.getTexture();
        if (result)
        {
            baseSprite.setTexture(*result);
        }
    }
    
    Tile& Tile::operator = (const Tile& other)
    {
        type = other.type;
        color = other.color;
        light_level = other.light_level;
        loc_x = other.loc_x;
        loc_y = other.loc_y;
        sf::Texture* result = other.baseSprite.getTexture();
        if (result)
        {
            baseSprite.setTexture(*result);
        }
        return *this;
    }
    
    赋值操作符应该是这样的:

    map[x][y] = tile;
    
    Tile::Tile(const Tile& other)
    : type(other.type)
    , color(other.color)
    , light_level(other.light_level)
    , loc_x(other.loc_x)
    , loc_y(other.loc_y)
    , baseSprite()
    {
        sf::Texture* result = other.baseSprite.getTexture();
        if (result)
        {
            baseSprite.setTexture(*result);
        }
    }
    
    Tile& Tile::operator = (const Tile& other)
    {
        type = other.type;
        color = other.color;
        light_level = other.light_level;
        loc_x = other.loc_x;
        loc_y = other.loc_y;
        sf::Texture* result = other.baseSprite.getTexture();
        if (result)
        {
            baseSprite.setTexture(*result);
        }
        return *this;
    }
    
    还有比这更多的内容,它似乎还可以由纹理的子矩形定义
    sf::Sprite
    ,并且它可能有更多需要注意的属性。例如,一个
    sf::Sprite
    也有用于其位置、旋转、全局颜色的getter和setter,所有这些都需要复制。在任何情况下,一旦全部完成,您就可以忘记指针混乱并实例化

    std::vector<std::vector<Tile> >
    
    std::vector
    相反。

    不确定是否有足够的信息来很好地回答这个问题。但是使用智能指针可能不是个坏主意。你需要查找RAII。删除磁贴时应该有一个处理其成员的析构函数。请查看智能指针,尤其是
    std::unique\u ptr
    。如果无法使用,请查看boost前置程序。为什么要删除
    磁贴的每个成员?它们本身不是指针,你有UB。是的,删除磁贴的每个成员没有任何作用。我正在研究解决方案的std::unique_ptrTank。我已经尝试实施这个解决方案好几个小时了。我最终使用2D向量运行了游戏,没有指针。但是,它加载瓷砖的速度比以前慢得多。这应该发生吗?无论如何,谢谢你到目前为止的帮助!我有一些关于为什么会这样的想法,但是这个聊天室对于那个对话来说太小了。你只需给我发电子邮件(见我个人资料页面上的电子邮件地址)即可继续车队。