C++ 如何在没有内存泄漏的情况下删除对象指针的2D向量?C++;和SFML
我有一个2D向量的平铺指针。每次加载不同的贴图时,我都希望删除向量中的所有平铺,释放内存,然后用不同的平铺重新填充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++){
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向量运行了游戏,没有指针。但是,它加载瓷砖的速度比以前慢得多。这应该发生吗?无论如何,谢谢你到目前为止的帮助!我有一些关于为什么会这样的想法,但是这个聊天室对于那个对话来说太小了。你只需给我发电子邮件(见我个人资料页面上的电子邮件地址)即可继续车队。