2011-06-18 12 views
18

मैं एक नई परियोजना में काम कर रहा हूं लेकिन मुझे एक समस्या का सामना करना पड़ रहा है जिसे मैं नहीं देख सकता कि क्यों विफल हो रहा है।_Block_Type_Is_Valid (pHead-> nBlockUse) त्रुटि

जब मैं इस पंक्ति को perfom पाठ हटा देता हूं तो मुझे त्रुटि _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 

तो मुझे लगता है समर्थक ब्लेम यह है कि जब मैं ऑब्जेक्ट टेक्स्ट को नष्ट करता हूं, तो TTF_Font को पॉइंटर नष्ट हो जाता है। लेकिन मुझे यकीन नहीं है क्योंकि जब मैं वेक्टर में ऑब्जेक्ट टेक्स्ट जोड़ता हूं तो मैं एक कॉपी-कन्स्ट्रक्टर का उपयोग करता हूं ताकि अलग-अलग पॉइंटर्स को बिना किसी समस्या के प्रतिलिपि मिल सके।

+0

आप कॉल स्टैक को देखने के लिए जो अपने कोड का अंतिम कॉल कि डिबगिंग विफलता का कारण बना था चलना था: यदि आप किसी ऑब्जेक्ट डबल हटाना

एक अन्य मामले में जहां ऐसा हो सकता है? (इसके अलावा, एसटीएल कंटेनर में रॉ पॉइंटर्स! मेरी आंखें! :)) –

+0

हां, यह केवल एक परीक्षण है जबकि मैं सभी एसटीएल कंटेनर में स्मार्ट पॉइंटर्स लागू करता हूं। मैं कॉल स्टैक की जांच करने जा रहा हूं। धन्यवाद। –

उत्तर

11

बस std::string का उपयोग करें। उस त्रुटि का अर्थ है कि आपने कुछ हटा दिया है, या ऐसा कुछ, एक समस्या है जो आपके पास नहीं होगी यदि आपने अपनी याददाश्त का प्रबंधन नहीं किया है। आपका कोड मेमोरी लीक और अन्य बग्स से भरा हुआ है जो आपके पास std::string के साथ नहीं होंगे।

+0

सहायता के लिए धन्यवाद। मैंने std :: स्ट्रिंग के लिए सभी char * को बदल दिया और समस्या के बिना काम किया। और उम्मीद है कि अगर यह पूछता है कि एसटीएल कंटेनरों में कच्चे पॉइंटर्स का उपयोग करने में कोई समस्या है, तो मैं उनमें से कुछ में auto_ptr का उपयोग करने में सोच रहा था, और साझा की गई अन्य वस्तुओं में shared_ptr की आवश्यकता है, यह वास्तव में निष्पक्ष है? –

+0

@ oscar.rpr: आप मानक कंटेनरों में 'auto_ptr' का उपयोग नहीं कर सकते हैं। यह समस्या C++ 11 में तय की जाएगी, लेकिन सी ++ 03 में, आपको 'shared_ptr' का उपयोग करना होगा- भले ही केवल एक संदर्भ हो। – Puppy

+0

सहायता के लिए धन्यवाद, इसलिए मैं एसटीएल कंटेनर में कच्चे पॉइंटर्स के बजाय shared_ptr का उपयोग करूंगा। –

9

जो मैं देख सकता हूं, त्रुटि को Text के लिए डिफ़ॉल्ट ctor के साथ करना है। आप 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") char* संकेत दिए गए गैर स्थिरांक करने के लिए बाध्य करने के लिए, के रूप में इस कोड में देखा अनुमति देता है। सी ++ 11 ने शुक्रिया को निश्चित रूप से तय किया है और यह वास्तव में अब संकलित नहीं होना चाहिए। अब, एक शाब्दिक स्ट्रिंग को हटाने से स्पष्ट रूप से काम नहीं होता है, क्योंकि स्ट्रिंग को .exe के केवल-पढ़ने वाले अनुभाग में रखा जाता है और ऐसा delete सक्षम नहीं है। मुझे लगता है कि यह वह जगह है जहां से आपकी त्रुटि आती है, यदि आप Text ऑब्जेक्ट को शाब्दिक स्ट्रिंग से तुरंत चालू करते हैं।

नोट यह भी होता है कि अगर आप इसे एक char[] ढेर पर बनाया से बनाने के लिए:

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

Foo के रूप में अब delete एक ढेर-वस्तु की कोशिश करेंगे।

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

धन्यवाद, मैंने पहले से ही प्रत्येक char * को std :: string में बदलने में समस्या हल कर दी है, क्योंकि यह स्मृति रिसाव और अन्य समस्याओं का कारण बन रहा है। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^