Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Delete qui fait planter le programme  (Lu 1952 fois)

0 Membres et 1 Invité sur ce sujet

Koseki

  • Newbie
  • *
  • Messages: 6
    • Voir le profil
Delete qui fait planter le programme
« le: Mai 10, 2018, 10:39:13 pm »
Bonjour!

Petit soucis aujourd'hui...
J'ai créer un logger pour écrire des messages dans une console ou un fichier.
Mais j'ai un petit problème! Lorsque je veux affecter un nouveau logger(pour switcher entre différents fichiers ou la console) mon programme plante.
Après quelques recherches, je me suis aperçu que c'est mon delete qui fait planter mon programme!

Le truc étrange, c'est qu'on rentre deux fois d'affiler dans la fonction destroy()... et à chaque fois, le delete ne fonctionne pas.

Quelqu'un aurait une idée d'où ça pourrais venir?

Voici mon retour dans la console:
On change le logger
Destruction de l'objet...
Objet détruit
Objet re-définit
Teste
On change le logger
Destruction de l'objet...
Destruction de l'objet...

Voici le code dans mon main:
AbstractLogger::setLogger(new ConsoleLogger());
AbstractLogger::log() << "Teste \n";

AbstractLogger.hpp:
#ifndef DEF_ABSTRACT_LOGGER
#define DEF_ABSTRACT_LOGGER

#include <iostream>

class AbstractLogger
{
    public:
        AbstractLogger();
        virtual ~AbstractLogger();

        static void setLogger(AbstractLogger* logger); // Permet de modifier le logger à utiliser
        static AbstractLogger& log(); // Renvoie une référence sur le logger actuel

        AbstractLogger& operator <<(const std::string& message); // Permet de logger ce qu'on veut en utilisant la syntaxe du C++(grace à la surcharge de l'opérateur <<)

    private:
        static void destroy(); // Détruit l'instance du logger, private pour éviter de l'appeler n'importe où

        virtual void write(const std::string& message) = 0; // Fonction purement virtuelle pour éviter d'instancier cette classe directement, elle nous servira à lancer l'écriture

        static AbstractLogger* m_instance; // Pointeur sur le logger actuel (singleton)
};

#endif // DEF_ABSTRACT_LOGGER

AbstractLogger.cpp
#include <iostream>
#include "../../include/Logger/AbstractLogger.hpp"
#include "../../include/Logger/ConsoleLogger.hpp"

AbstractLogger* AbstractLogger::m_instance = nullptr; // Bien sur, on initialise notre instance à nullptr

AbstractLogger::AbstractLogger()
{

}
AbstractLogger::~AbstractLogger()
{
    destroy();
}

void AbstractLogger::setLogger(AbstractLogger* logger)
{
    std::cout << "On change le logger" << std::endl;
    destroy();
    m_instance = logger;
    std::cout << "Objet re-définit"<< std::endl;
}
void AbstractLogger::destroy()
{
    std::cout << "Destruction de l'objet..."<< std::endl;
    delete m_instance;
    std::cout << "Objet détruit"<< std::endl;
    m_instance = nullptr;
}

AbstractLogger& AbstractLogger::log()
{
    return *m_instance;
}

AbstractLogger& AbstractLogger::operator <<(const std::string& message)
{
    write(message);
    // On renvoie notre instance pour pouvoir chaîner les appels à << pour garder le même fonctionnement que std::cout <<
    return log();
}
 

ConsoleLogger.hpp
#ifndef DEF_CONSOLE_LOGGER
#define DEF_CONSOLE_LOGGER

#include <iostream>
#include "AbstractLogger.hpp"

class ConsoleLogger : public AbstractLogger
{
    public:
        ConsoleLogger();
    protected:
        virtual void write(const std::string& message);
};

#endif // DEF_CONSOLE_LOGGER
 

ConsoleLogger.cpp
#include <iostream>
#include "../../include/Logger/ConsoleLogger.hpp"

ConsoleLogger::ConsoleLogger()
{

}

void ConsoleLogger::write(const std::string& message)
{
    std::cout << message;
}

 

Pour tester le bon fonctionnement de mon logger, j'ai rajouter ce code dans le destructeur d'une de mes classes(pour tester l'écriture dans un fichier suite à une erreur, mais pour mes testes, je suis passer à l'écriture dans la console)
AbstractLogger::setLogger(new ConsoleLogger());
AbstractLogger::log() << "ALL GREEN";
C'est pour cela que nous avons 2 changements de logger.

J'ai essayer d'enlever le delete et l'application fonctionne niquel...

Merci à tous ceux qui pourront m'aider!

kimci86

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
Re: Delete qui fait planter le programme
« Réponse #1 le: Mai 11, 2018, 12:35:24 am »
Le problème est que destroy appelle le destructeur de l'instance via un delete qui lui-même appelle destroy.

Je recommande de stocker l'instance dans un std::unique_ptr, ce qui libérera la mémoire automatiquement.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Delete qui fait planter le programme
« Réponse #2 le: Mai 11, 2018, 08:07:33 am »
Et quel est le rapport avec SFML ? Il y a des forums plus spécialisés pour les questions de C++ ; ici on essaye dans la mesure du possible de rester concentrés sur SFML ;)
Laurent Gomila - SFML developer

Koseki

  • Newbie
  • *
  • Messages: 6
    • Voir le profil
Re: Delete qui fait planter le programme
« Réponse #3 le: Mai 11, 2018, 11:18:32 am »
Le problème est que destroy appelle le destructeur de l'instance via un delete qui lui-même appelle destroy.

Je recommande de stocker l'instance dans un std::unique_ptr, ce qui libérera la mémoire automatiquement.
Ah mais oui, pourquoi je n'y ait pas pensé >_> Merci kimci86!

Et quel est le rapport avec SFML ? Il y a des forums plus spécialisés pour les questions de C++ ; ici on essaye dans la mesure du possible de rester concentrés sur SFML ;)
Oui, désolé Laurent, j'éviterais à l'avenir les questions hors SFML :)