3 votes

erreur de segmentation lors de l'accès à une chaîne de caractères membre d'une classe

J'ai une classe Message qui a un std::string en tant que membre de données, défini comme suit :

class Message
{
// Member Variables
    private:
        std::string text;
        (...)

// Member Functions
    public:
        Message(const std::string& t)
        : text(t) {}

        std::string getText() const {return text;}
        (...)
};

Cette classe est utilisée dans un vecteur d'une autre classe, comme ceci :

class Console
{
// Member Variables
    private:
        std::vector<Message> messageLog;
        (...)

// Member Functions
    public:
        Console()
        {
            messageLog.push_back(Message("Hello World!"));
        }

        void draw() const;
};

En draw() , il y a un itérateur qui appelle getText() . Si c'est le cas, le programme s'arrête. J'ai déterminé que text est valide à l'intérieur du Message constructeur. Cependant, je ne peux pas dire s'il est valide à l'intérieur de Console . Je suppose que c'est le cas, mais si j'essaie d'inspecter les indices de Console dans le messageLog, gdb me dit ceci :

(gdb) p messageLog[0] One of the arguments you tried to pass to operator[] could not be converted to what the function wants.

Quelqu'un sait-il ce qui se passe ?

EDIT : voici draw() . TCODConsole fait partie d'une bibliothèque curses que j'utilise, et donc cette fonction imprime chaque message dans Console à une partie de l'écran des malédictions. TL y BR sont Point des objets membres (deux ints) qui indiquent où dessiner sur l'écran Console . J'ai laissé de côté certaines parties de Message y Console dans la question originale afin de rendre les choses plus claires, mais si vous avez besoin que je poste les classes entières, je peux le faire. Ils ne sont pas trop longs.

void Console::draw() const
        {
            int x = TL.getX(), y = TL.getY();
            int width = BR.getX() - TL.getX();
            int height = BR.getY() - TL.getY();

            // draw the Console frame
            TCODConsole::root->printFrame(x, y, width, height, true);

            // print the Console's messages
            vector<Message>::const_iterator it;
            for(it=messageLog.begin(); it<messageLog.begin()+height-1; ++it)
            {
                string message = "%c" + it->getText();
                TCODConsole::setColorControl(TCOD_COLCTRL_1, 
                                             it->getForeColor(),
                                             it->getBackColor());
                y += TCODConsole::root->printRectEx(x, y, width, height,
                                                    TCOD_BKGND_NONE,
                                                    TCOD_LEFT,
                                                    message.c_str(),
                                                    TCOD_COLCTRL_1);
            }
        }

2voto

rturrado Points 1195

Je pense qu'au moment où vous utilisez it->getText() l'itérateur est NULL. Ajouter une vérification it != messageLog.end() lorsque vous parcourez le tableau, et avant d'appeler it->getText() .

0voto

t0rx Points 163

Est-il définitivement std::vector messageLog et non std::vector<Message> messageLog ? Cela semble un peu étrange.

0voto

Zoltan Points 912

Quel est le rapport entre la hauteur et l'indice du vecteur ? Vous avez :

messageLog.begin()+height-1;

Pourquoi ajoutez-vous les coordonnées de l'écran à l'itérateur ? Cela semble être votre problème et vous êtes probablement en train de surindexer et c'est pourquoi vous obtenez un SIGSEGV.

Ce que vous voulez probablement, c'est simplement itérer sur tous les messages du vecteur et les afficher à un endroit particulier de l'écran. Je vois ce que vous essayez de faire, mais si vous essayez de calculer la limite de l'écran en utilisant l'itérateur, vous ne vous y prenez pas de la bonne façon. Essayez de lancer un compteur ou d'obtenir messageLog.size() et recalcule la hauteur à chaque itération. Pour ce qui est de la boucle, il suffit de faire :

for(it=messageLog.begin(); it!=messageLog.end(); ++it)

-2voto

4thWallBREAKER Points 1

C'est probablement parce que le champ d'application de la Message créé dans l'objet Console est simplement la méthode Console méthode. Ainsi, si votre programme tente d'accéder à cet objet dans une autre méthode, par exemple draw vous obtiendrez cette erreur de segmentation, puisque cet objet est supprimé après l'exécution.

Essayez ceci (insérez simplement un new mot-clé) :

    Console()
    {
        messageLog.push_back(new Message("Hello World!"));
    }

Dans ce cas, l'objet n'est pas supprimé après la fin de la console.

N'oubliez pas de supprimer les objets créés lorsque votre programme n'en a plus besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X