0

So my program works just fine but when i define the MapTile's destructor ( which just calls delete operator for sprite and a texture) it throws access violation at the start of the program. Can someone please help me? Here's the code:

Map.h

#pragma once
#include "State.h"

class MapTile
{
    struct MapObject
    {
        float x, y;
        bool is_ground = false;
        MapObject(float x, float y, bool is_ground = false) : x{x}, y{y}
        {
        }
    };
    char type;
    std::vector<MapObject> objects;
    sf::Texture* texture;
    sf::Sprite* sprite;

public:
    explicit MapTile(std::string texture_path);
    ~MapTile();
    void render(sf::RenderWindow* w);
    void load(std::string file_path, sf::Vector2i& map_size, char type);
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class Map // contains tilemap
{
    sf::Thread thread; // on this thread, load the map
    std::ifstream map_file;
    sf::Vector2i size;

    std::vector<MapTile> tiles;
    std::string path; // Path to map file

    void load();
public:
    explicit Map(std::string path);
    ~Map();
    void render(sf::RenderWindow* w);
};

Map.cpp

#include "Map.h"

MapTile::MapTile(std::string texture_path) : type{type}
{
    // Load texture's texture and set up the sprite
    texture = new sf::Texture;
    texture->loadFromFile(texture_path);
    sprite = new sf::Sprite(*texture);
}

MapTile::~MapTile()
{
    delete texture;
    delete sprite;
}

void MapTile::load(std::string file_path, sf::Vector2i& map_size, char type)
{
    std::ifstream file;
    file.open(file_path);

    file.seekg(8);
    // Assign the tiles based off map
    std::string row;
    for (int i = 0; i < map_size.y; i++)
    {
        std::getline(file, row);

        for (int j = 0; j < row.size(); j++)
        {
            if (row[j] == type)
            {
                objects.push_back(MapObject{ j * 40.f, i * 40.f });
            }
        }
    }

    file.close();
}

void MapTile::render(sf::RenderWindow* w)
{
    for (int i = 0; i < objects.size(); i++)
    {
        sprite->setPosition(objects[i].x, objects[i].y);
        w->draw(*sprite);
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Map::load()
{
    std::ifstream file(path);
    file >> size.x >> size.y >> std::ws;
    file.close();

    tiles.push_back(MapTile{ "Textures/sky.png" }); // Sky
    tiles[0].load(path, size, ' ');
}

Map::Map(std::string path) : thread{&Map::load, this}, path{path}
{
    thread.launch();
}

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

void Map::render(sf::RenderWindow* w)
{
    for (int i = 0; i < tiles.size(); i++)
    {
        tiles[i].render(w);
    }
}

The exception says: Exception thrown at 0x00007FFCD15EB2A6 (sfml-graphics-d-2.dll) in myProgram.exe: 0xC0000005: Access violation reading location 0x0000000000000008.

And the adress is usually 0x0000000000000008 or 0xFFFFFFFFFFFFFFFF

Please can someone tell me what is wrong whis this destructor?

When the destructor is removed from the code, everything just works normally. When the destructor is defined - it throws an exception in MapTile::render() method

Justro
  • 11
  • 1
  • Your `MapTile` class violates the rule of 3 / 5 /0: [https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – drescherjm Feb 27 '23 at 17:03
  • 1
    *When the destructor is removed from the code, everything just works normally.* -- "When I remove the brakes from my car, the car works normally". – PaulMcKenzie Feb 27 '23 at 17:08
  • `std::vector tiles;` -- Your class has incorrect copy semantics, thus cannot be placed in a vector safely. Don't blame the destructor -- it is doing its job. `int main() { MapTile m1("whatever"); MapTile m2 = m1; }` -- Just that alone will cause issues. – PaulMcKenzie Feb 27 '23 at 17:12
  • Minor point: the constructor for `MapObject` ignores its third parameter. – Pete Becker Feb 27 '23 at 17:14
  • What are you trying to do here: `delete &tiles[i];`? The vector manages its own memory and the memory of its elements. – Kevin Feb 27 '23 at 17:22
  • ok thanks i will fix it – Justro Feb 27 '23 at 17:48

0 Answers0