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

时间:2014-06-06 17:21:27

标签: c++ pointers memory-leaks sfml 2d-vector

我有一个Tile指针的2D矢量。每次我加载一个不同的地图我想删除向量中的所有Tiles,释放内存,然后用不同的tile重新填充它。

std::vector<std::vector<Tile*>> map;

这是我的Tile课程:

#ifndef _TILE_H
#define _TILE_H

#include <SFML\Graphics.hpp>

class Tile
{

public:
    int type;
    int color;
    int light_level;
    int loc_x, loc_y;

    Tile();
    ~Tile();

    sf::Sprite baseSprite;

    void Draw(int x, int y, sf::RenderWindow* rw);

    void setTexture(sf::Texture& texture);
};

#endif

我填写这样的矢量:

map[x][y] = tile;

问题是,每次我用Tiles重新填充向量时,我的记忆会继续填满,直到游戏崩溃。我的问题是,如何正确删除向量中的所有内容以释放内存?

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

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() 

如果需要任何其他代码,请告诉我,谢谢。

1 个答案:

答案 0 :(得分:1)

Tile类判断,使用Tile指针而不是直接在向量中使用Tile s似乎很愚蠢。这是解决问题的可能方法:

  1. 定义一个复制构造函数,即定义Tile::Tile(const Tile&)应该做什么(它应该将所有数据成员复制到新构建的tile中)。
  2. 定义一个赋值运算符,即定义Tile& Tile::operator=(const Tile&)应该执行的操作(它应该调用其所有数据成员和operator=上的所有return *this函数。)
  3. 现在乍一看这似乎没问题,但是我查看了sf::Sprite文档,并且没有为sf::Sprite定义复制构造函数和赋值运算符。似乎sprite只能通过sf::Texture创建。幸运的是,每个sf::Sprite都会公开一个返回其自己的绑定sf::Texture的公共成员函数。但是,查看sf::Sprite::getTexture()的文档,它会将指针返回给sf::Texture,如果尚未绑定到{{1},则可能为NULL }}。您应该在sf::Sprite的复制构造函数和赋值运算符中检查它。

    然后,复制构造函数应该如下所示:

    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还有其位置,旋转,全局颜色以及需要复制的所有内容的getter和setter。无论如何,一旦完成,你就可以忘记指针混乱并实例化

    sf::Sprite

    代替。