Search code examples
c++sfml

C++ Can't Return A Vector of Textures


I have a class that keeps track of objects I've declared. This class also has a vector as a member. I add textures through a function (probably, there is a leak). I am probably doing a mistake about c++ itself, not sfml.

in Item.h:

    #ifndef ITEM_H
    #define ITEM_H

    class ItemTexture {
        public:
            static std::vector<ItemTexture*> textures;
            std::vector<sf::Texture*> variation;
            ItemTexture(std::string file);
            void addTexture(std::string file);
            static sf::Texture getTexture(int id, int no) {
                return *textures[id]->variation[no]; //Program crashes here
            }
            static void declare_textures();
    };

#endif

in the Item.cpp:

#include "Item.h"
std::vector<ItemTexture*> ItemTexture::textures;
ItemTexture::ItemTexture(std::string file)
{
    sf::Texture *tex = new sf::Texture;
    tex->setSmooth(false);
    tex->loadFromFile(file);
    variation.push_back(tex);
    textures.push_back(this);
    delete tex;
}
void ItemTexture::addTexture(std::string file)
{
    sf::Texture *tex = new sf::Texture;
    tex->setSmooth(false);
    tex->loadFromFile(file);
    variation.push_back(tex);
    delete tex;
}

This doesn't give any error messages, program crashes at the line return *textures[id]->variation[no];


Solution

  • There are two possibilities for crash in your code at *textures[id]->variation[no];

    1. You must be creating an object of ItemTexture in stack and then the constructor of ItemTexture is pushing back this pointer to the vector textures. If the object you created goes out of scope, the vector textures will have a dangling pointer since the object it is pointing to is already destroyed. Or you could be deleting it like you have done with sf::Texture as explained in second possible reason below. This causes *textures[id] part of *textures[id]->variation[no]; to cause crash.

    Solution: Allocate it dynamically and don't delete it till you are done with that( calls like getTexture()).

    1. You are creating object Texture dynamically using sf::Texture *tex = new sf::Texture; and deleting that with delete tex;. So whatever you pushed with variation.push_back(tex); becomes dangling pointer. variation is full of dangling pointers and when you access it, you application crashes. This causes variation[no] part of *textures[id]->variation[no]; to cause crash if above one is not the issue.

    Solution: Remove delete tex; and release it in destructor.