2011-06-18 6 views
18

新しいプロジェクトで作業していましたが、なぜ失敗するのか分からない問題が発生しました。_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 

だから私はプロだと思いますblemは、オブジェクトtextYを破棄すると、TTF_Fontへのポインタが破棄されるということです。しかし、私はベクトルにオブジェクトのテキストを追加するときに私はコピーコンストラクタを使用するので、別のポインタが問題なくコピーを取得するため、私は確信していません。

+0

デバッグの失敗の原因となったコード内の最後の呼び出しだったかを確認するためにコールスタックを歩いていましたか? (STLコンテナの生のポインタ!私の目!:)) –

+0

はい、それはすべてのSTLコンテナにスマートポインタを実装している間の唯一のテストです。私はコールスタックをチェックするつもりです。ありがとう。 –

答えて

11

std::stringを使用してください。そのエラーは、あなたが自分のメモリを管理していない場合には持っていなかったような、何かを何かを削除したことを意味します。あなたのコードは、メモリリークや他のバグで埋もれています。std::stringにはありません。

+0

助けてくれてありがとう。私はstd :: stringのすべてのchar *を変更して問題なく動作します。私は、STLコンテナのrawポインタを使用する際に問題がある場合は、auto_ptrをいくつか使用し、必要な他のオブジェクトのshared_ptrを使用することを考えていました。本当に必要ですか? –

+0

@ oscar.rpr:標準コンテナでは 'auto_ptr'を使用できません。この問題はC++ 11では修正されますが、C++ 03では参照が1つしかない場合でも 'shared_ptr'を使用する必要があります。 – Puppy

+0

助けてくれてありがとう、私はSTLの容器で生のポインタの代わりにshared_ptrを使用します。 –

9

私が見ることができますから、エラーはTextのデフォルトのctorと関係しています。 char*ポインタを取り込み、文字列のスペースを割り当てますが、実際にはtextstrにコピーするのではなく、単にポインタを割り当てます。あなたはコピーctorで正しいことを行う。

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

    ~Foo(){ 
     delete str; 
    } 

private: 
    char* str; 
}; 

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

C++ 03(後方互換性のために...)このコードで見られるようにリテラル文字列("hi")は、非const char*ポインタにバインドすることができます:さて、この例を考えてみましょう。ありがたいことにこれを修正しました。これは実際にはコンパイルされません。文字列が.exeの読み取り専用セクションに置かれ、そのままdeleteがないため、リテラル文字列を削除することはできません。私はこれがあなたのエラーがどこから来るのかと思います。Textオブジェクトをリテラル文字列からインスタンス化すると、あなたがスタック上に作成したchar[]からそれを作成する場合、これがまた起こること

注:Fooとして

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

は今deleteスタック・オブジェクトにしようとします。

あなたがオブジェクトをダブル削除した場合、これは起こるかもしれないもう一つのケースがある:

char* text = new char[3]; 
Foo f(text); 
delete text; 
+0

ありがとう、私はすでに、メモリリークやその他の問題を引き起こしていたので、すべてのchar *をstd :: stringに変更する問題を解決しました。 –

関連する問題