Ошибка _Block_Type_Is_Valid (pHead-> nBlockUse)
Я работаю в новом проекте, но сталкиваюсь с проблемой, которую я не вижу, почему сбой.
Когда я выполняю эту строку, удалите текст. Дайте мне ошибку _Block_Type_Is_Valid (pHead- > nBlockUse). Так что я делаю неправильно?
Это исходный код:
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
Итак, я думаю, проблема в том, что когда я уничтожаю объект textY, указатель на TTF_Font уничтожается. Но я не уверен, потому что, когда я добавляю объект Text в вектор, я использую конструктор-копию, поэтому разные указатели получили копию без проблем.
Ответы
Ответ 1
Просто используйте std::string
. Эта ошибка означает, что вы дважды удалили что-то или что-то в этом роде, проблему, которой не было бы, если бы вы не управляли своей собственной памятью. Ваш код усеян утечками памяти и другими ошибками, которые у вас не будут с std::string
.
Ответ 2
Из того, что я вижу, ошибка связана с по умолчанию ctor для Text
. Вы берете указатель char*
, выделяете пространство для строки, но на самом деле не копируете Text
в str
, а просто назначаете указатель! Однако вы делаете это правильно в копии ctor. Теперь рассмотрим этот пример:
class Foo{
public:
Foo(char* text){
str = text;
}
~Foo(){
delete str;
}
private:
char* str;
};
int main(){
Foo f("hi");
}
С++ 03 (для обратной совместимости...) позволяет литеральные строки ("hi"
) связываться с указателями non-const char*
, как показано в этом коде. С++ 11, к счастью, исправил это, и это на самом деле больше не компилируется. Теперь удаление литеральной строки, очевидно, не работает, так как строка помещается в раздел только для чтения .exe и как таковая не способна delete
. Я предполагаю, что именно здесь возникает ваша ошибка, если вы создаете экземпляр объекта Text
из строковой строки.
Обратите внимание, что это также происходит, если вы создаете его из char[]
, созданного в стеке:
char text[] = "hi";
Foo f(text);
поскольку Foo
теперь попытается delete
создать стек-объект.
Другой случай, когда это может произойти, заключается в двойном удалении объекта:
char* text = new char[3];
Foo f(text);
delete text;