web-dev-qa-db-fra.com

Erreur _Block_Type_Is_Valid (pHead-> nBlockUse)

Je travaillais sur un nouveau projet mais je rencontre un problème que je ne vois pas pourquoi échouer.

Quand je perfom cette ligne supprimer textY me donner l'erreur _Block_Type_Is_Valid (pHead-> nBlockUse). Alors qu'est-ce que je fais mal?

Voici le code source:

Text.h

 #ifndef TEXT_H
 #define TEXT_H

typedef boost::shared_ptr<Font>  FontPtr;

class Text
{
public:

    Text(FontPtr font, char *text)
    {
        str = new char[35];
        this->font = font;    str = text; 
    }

    Text(const Text& cSource);
    Text& operator=(const Text& cSource);

    ~Text();
    .
    .
    .
    .

private:
    FontPtr font;
    char *str;
    GLuint texture;
    GLfloat pos_x, pos_y, width, height;
};

 #endif 

Text.cpp

Text::Text(const Text& cSource)
{
    font = cSource.font;
    texture = cSource.texture;
    pos_x = cSource.pos_x;
    pos_y = cSource.pos_y;
    width = cSource.width;
    height = cSource.height;

    int sizeString = 35;
    if (cSource.str)
    {
        str = new char[sizeString];
        strncpy(str, cSource.str, sizeString);
    }

    else 
    {
        str = 0;
    }
}

Text& Text::operator=(const Text& cSource)
{
    delete[] str;

    font = cSource.font;
    texture = cSource.texture;
    pos_x = cSource.pos_x;
    pos_y = cSource.pos_y;
    width = cSource.width;
    height = cSource.height;

    int sizeString = 35;
    if (cSource.str)
    {
        str = new char[sizeString];
        strncpy(str, cSource.str, sizeString);
    }

    else 
    {
        str = 0;
    }

    return *this;
}

Text::~Text()
{
    delete[] str;
}

Font.h

#ifndef FONT_H
#define FONT_H

class Font
{
public:

    Font(TTF_Font *font, SDL_Color color)
    {
        this->font = font;    this->color = color; 
    }

    ~Font();
    .
    .
    .

private:
    TTF_Font *font;
    SDL_Color color;

};

#endif

Font.cpp

Font::~Font()
{
    TTF_CloseFont(font);
}

CGameApplication.cpp

.
.
.
.
void CGameApplication::initializeApplicationFonts()
{
    TTF_Font* font;
    SDL_Color color;

    font = TTF_OpenFont("test.ttf", 15);

    color.r = color.g = color.b = 255;

    GApp->addFont(font, color);

    Text *text = new Text(GApp->getFonts().at(0), " ");
    text->setTexture( CTextM->textToGLTexture(GApp->getFonts().at(0), text) );
    text->setPosX(20);  text->setPosY(20);

    GApp->addText(new Text(*text));

    Text *textY = new Text(GApp->getFonts().at(0), " ");
    textY->setTexture( CTextM->textToGLTexture(GApp->getFonts().at(0), textY) );
    textY->setPosX(80);  textY->setPosY(20);

    GApp->addText(new Text(*textY));
    delete textY;                 //-----> This line crashes the program with that error
}
.
.
.

GameApp.h

#ifndef GAMEAPP_H
#define GAMEAPP_H


class GameApp
{
public:
    GameApp(){
    }

    //~GameApp();

    void addFont(TTF_Font *font, SDL_Color color) { 
        vFonts.Push_back(FontPtr( new Font(font, color) ) ); }

    vector<FontPtr> getFonts() { return vFonts; }

    void addText(Text *text) { 
        vTexts.Push_back(new Text(*text));}

private:
    SDL_Surface *gameMainSurface;
    vector<Image*> vImages; 
    std::vector<FontPtr> vFonts;
    vector<Text*> vTexts;
    vector<Tile*> vTiles;
    Map *currentMap;
};

#endif

Je pense donc que le problème est que lorsque je détruis l'objet textY, le pointeur vers TTF_Font est détruit. Mais je ne suis pas sûr car lorsque j'ajoute un objet Text dans le vecteur, j'utilise un constructeur de copie pour que les différents pointeurs soient copiés sans problème.

18
oscar.rpr

Utilisez simplement un std::string. Cette erreur signifie que vous avez supprimé deux fois quelque chose, ou quelque chose comme ça, un problème que vous n'auriez pas si vous ne gériez pas votre propre mémoire. Votre code est jonché de fuites de mémoire et d'autres bogues que vous n'aurez pas avec std::string.

11
Puppy

D'après ce que je peux voir, l'erreur a à voir avec le ctor par défaut pour Text. Vous prenez un char* pointeur, alloue de l'espace pour la chaîne, mais ne copiez pas réellement le text dans str, mais affectez simplement le pointeur! Vous le faites correctement dans le ctor copie cependant. Maintenant, considérez cet exemple:

class Foo{
public:
    Foo(char* text){
        str = text;
    }

    ~Foo(){
        delete str;
    }

private:
    char* str;
};

int main(){
    Foo f("hi");
}

C++ 03 (pour une compatibilité descendante ...) autorise les chaînes littérales ("hi") pour se lier à un non-const char* pointeurs, comme vu dans ce code. Heureusement, C++ 11 a corrigé cela et cela ne devrait plus être compilé. Maintenant, la suppression d'une chaîne littérale ne fonctionne évidemment pas, car la chaîne est placée dans la section en lecture seule du fichier .exe et en tant que telle n'est pas deleteable. Je suppose que c'est de là que vient votre erreur, si vous instanciez un objet Text à partir d'une chaîne littérale.

Notez que cela se produit également si vous le créez à partir d'un char[] créé sur la pile:

char text[] = "hi";
Foo f(text);

comme Foo va maintenant essayer de delete un objet pile.

Un autre cas où cela peut se produire est que si vous double-supprimez un objet:

char* text = new char[3];
Foo f(text);
delete text;
10
Xeo