2017-05-28 3 views
0

Ceci est un problème de gestion de la mémoire C++ donc j'ai choisi de demander ici. Je crée un jeu en SFML. J'ai déjà utilisé SDL auparavant et la gestion de mes textures était très simple mais SFML fonctionne différemment.Gestion de la mémoire SFML Texture

Ma configuration du projet est quelque chose comme ceci:

class Game 
//create window and initialize game stuff 

class Character 
/*initializes its own textures and is also responsible for updating itself 
as well as drawing itself*/ 

int main() 
/*create an instance of Game -> Create an instance of Character and 
runGame. I will implement the drawing and updating properly when I 
implement a scene graph and scene nodes but for now updating and drawing is 
done via global functions called by the Game Class*/ 

Le défi pour moi était que l'utilisation d'un pc de texture dans la classe de caractères pour les résultats d'image Sprite dans un rectangle blanc en cours d'élaboration. Ainsi, le Sprite de personnage perd son lien Texture et SFML trace simplement un rectangle blanc. Pour résoudre ce problème, j'ai créé un pointeur de texture brut et l'initialiser dans le constructeur de caractères. Cela fonctionne et le Sprite est dessiné correctement.

//inside character.hpp 
sf::Texture *texture; 

//in Character constructor 
texture= new (sf::Texture); 

Cela signifie que je dois gérer la mémoire et que le code est moche.

J'ai essayé de gérer la mémoire allouée (je pense) pour éviter une fuite de mémoire:

Character::~Character() 
{ delete texturePtr; } 

mais qui ne va pas évidemment. J'ai également essayé de supprimer character.Texture à la fin de main() quand je quitte l'application mais cela provoque aussi une erreur.

J'ai alors essayé de faire utiliser un uinque_ptr dans le constructeur de caractères:

std::unique_ptr<sf::Texture> texture(new sf::Texture); 
//load Texture from Resource Manager instance 

et Dessine un joli rectangle bleu marine noir au lieu du Sprite Texture. Je ne suis pas sûr comment ou si je peux déclarer et ensuite initialiser un unique_ptr.

Je pense que j'ai une fuite de mémoire et si oui, comment utiliser correctement les pointeurs intelligents ou gérer correctement ma propre mémoire?

J'ai ajouté un peu plus de détails et de code que j'ai réalisé que j'étais vague. De plus, j'interroge la texture et je l'utilise pour définir les dimensions de Sprite Rect de manière à ce qu'elle soit chargée, mais pour être sûre, j'ai une fonction logger qui vérifie si une ressource que j'appelle est chargée ou non.

+0

Vous ne nous avez pas donné assez de code pour voir ce que vous faites mal. Cela dit, utiliser 'unique_ptr' est probablement une bonne idée. Si votre texture sort bleue, cela ressemble à un bug d'initialisation. En outre, pensez à utiliser 'make_unique' au lieu de' unique_ptr <...> toto (nouveau quelquechose) '. – Rook

+0

Vous avez dit que vous aviez des problèmes avec votre ancienne façon de le faire ... mais jamais * demandé * à ce sujet. Vous cherchez des solutions à un problème que vous ne devriez même pas avoir. Vous devriez * poser la question sur votre premier problème * des sprites blancs. – nvoigt

Répondre

2

Si le sf::Texture est membre de Character alors il ne sont hors de portée jusqu'à ce que votre Character instance ne. Utilisez les points de rupture du débogueur pour suivre ce qui se passe. Lancez un point de rupture dans le destructeur de Character et sf::Texture et parcourez vos séquences de démarrage et d'arrêt. Ou utilisez le journal pour imprimer des messages comme: "Character :: ~ called."


Je pense que je suis une fuite de mémoire et si oui, comment puis-je utiliser correctement les pointeurs intelligents ou gérer ma propre mémoire correctement?

Examinez toutes les hypothèses, y compris celle pour laquelle vous chargez correctement la texture. Jusqu'à ce que vous voyiez la texture dessiner sur l'écran, vous n'avez pas la preuve que vous l'avez chargé. (À moins que vous voulez un rectangle bleu marine.Je ne sais pas ce que vous essayez de dessiner.Je suppose un sprite de personnage.)

De SFML Docs:

La fonction loadFromFile peut parfois échouer sans raison évidente. Tout d'abord, vérifiez le message d'erreur que SFML imprime sur la sortie standard (vérifiez la console). Si le message ne parvient pas à ouvrir le fichier, assurez-vous que le répertoire de travail (qui est le répertoire auquel tout chemin de fichier sera interprété) est ce que vous pensez: Lorsque vous exécutez l'application depuis votre environnement de bureau, le répertoire de travail est le dossier exécutable. Cependant, lorsque vous lancez votre programme depuis votre IDE (Visual Studio, Code :: Blocks, ...), le répertoire de travail peut parfois être défini dans le répertoire du projet. Cela peut généralement être changé assez facilement dans les paramètres du projet.

Jusqu'à ce que vous voyiez une fuite dans un détecteur de fuite, vous ne pouvez vraiment pas supposer que vous fuyez la mémoire. Il existe des trackers de mémoire tiers que vous pouvez ajouter à votre programme.

Encore une fois, utilisez un point de rupture de débogage dans le destructeur sf::Texture pour arrêter l'exécution et voir exactement où vous vous désengagez (si cela s'avère être le problème). Vous devriez vraiment lire et suivre Minimal, Complete, and Verifiable example. Pour tout ce que nous savons que vous pourriez faire quelque chose comme ceci:

class Character{ 
    sf::Sprite mySprite; 

    public: 
    Character(){ 
     sf::texture aTex; 
     aTex.loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png"); 

     mySprite.setTexture(aTex); 
    } 
} 

// attempt 2 
class Character{ 
    sf::Sprite mySprite; 

    public: 
    Character(){ 
     std::unique_ptr<sf::Texture> texture(new sf::Texture); 
     texture->loadFromFile("c:\users\noob\Desktop\myawesomegame\stripper.png"); 

     mySprite.setTexture(*texture); 
    } 
} 

Et l'erreur serait évidente.

+0

J'utilise MSVC++ dans Visual Studio 2013 et j'ai lu sur le suivi des fuites mais je voulais être sûr avant d'entrer dans une phase de codage. J'ai édité ma question pour ajouter un peu plus de détail mais de votre réponse, vous semblez suggérer que je devrais cesser de m'inquiéter de la suppression du pointeur cru jusqu'à ce que j'aie un bogue de fuite de mémoire. – zimspy