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.
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
.
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 delete
able. 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;