2011-06-18 14 views
18

Tôi đã làm việc trong một dự án mới nhưng tôi gặp phải một vấn đề mà tôi không thể thấy tại sao không thành công._Block_Type_Is_Valid (pHead-> nBlockUse) Lỗi

Khi tôi perfom dòng này xóa textY cho tôi lỗi _Block_Type_Is_Valid (pHead-> nBlockUse). Vậy tôi đang làm gì sai?

Đây là mã nguồn:

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 

Vì vậy, tôi nghĩ rằng pro blem là khi tôi phá hủy đối tượng textY, con trỏ tới TTF_Font bị hủy. Nhưng tôi không chắc chắn vì khi tôi thêm một đối tượng Văn bản trong vectơ, tôi sử dụng một bản sao-constructor để các con trỏ khác nhau được sao chép mà không có vấn đề gì.

+0

Cậu đi bộ lên các cuộc gọi stack để xem đó là cuộc gọi cuối cùng trong mã của bạn gây ra sự thất bại gỡ lỗi? (Ngoài ra, Raw Con trỏ trong container STL! Mắt tôi! :)) –

+0

Vâng, nó chỉ là một thử nghiệm trong khi tôi thực hiện con trỏ thông minh trong tất cả các container STL. Tôi sẽ kiểm tra ngăn xếp cuộc gọi. Cảm ơn. –

Trả lời

11

Chỉ cần sử dụng std::string. Lỗi đó có nghĩa là bạn đã xóa một thứ gì đó hoặc một cái gì đó tương tự như vậy, một vấn đề mà bạn sẽ không gặp phải nếu bạn không quản lý bộ nhớ của chính mình. Mã của bạn bị phân tán với rò rỉ bộ nhớ và các lỗi khác mà bạn không có với std::string.

+0

Cảm ơn sự giúp đỡ. Tôi đã thay đổi tất cả các char * cho std :: string và làm việc mà không có vấn đề. Và mong đợi nó không phải là vấn đề nếu tôi hỏi, nếu có một vấn đề trong sử dụng con trỏ nguyên trong container STL, tôi đã suy nghĩ trong sử dụng auto_ptr trong một số người trong số họ, và shared_ptr trong các đối tượng khác mà nó cần thiết, nó thực sự là cần thiết? –

+0

@ oscar.rpr: Bạn không thể sử dụng 'auto_ptr' trong vùng chứa tiêu chuẩn. Vấn đề này sẽ được sửa trong C++ 11, nhưng trong C++ 03, bạn sẽ phải sử dụng 'shared_ptr'- ngay cả khi chỉ có một tham chiếu. – Puppy

+0

Cảm ơn sự giúp đỡ, vì vậy tôi sẽ sử dụng shared_ptr thay vì con trỏ thô trong các container STL. –

9

Từ những gì tôi có thể thấy, lỗi phải làm với ctor mặc định cho Text. Bạn lấy con trỏ char*, phân bổ không gian cho chuỗi, nhưng không thực sự sao chép text vào str, nhưng chỉ cần gán con trỏ! Bạn làm điều đó đúng trong ctor sao chép mặc dù. Bây giờ, hãy xem xét ví dụ sau:

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

    ~Foo(){ 
     delete str; 
    } 

private: 
    char* str; 
}; 

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

C++ 03 (đối ngược tương thích ...) cho phép các chuỗi chữ ("hi") để ràng buộc để không const char* con trỏ, như đã thấy trong mã này. C++ 11 may mắn cố định điều đó và điều này thực sự không còn biên dịch. Bây giờ, xóa một chuỗi chữ rõ ràng không hoạt động, vì chuỗi được đặt trong phần chỉ đọc của .exe và vì vậy không phải là delete. Tôi đoán đây là nơi mà lỗi của bạn xuất phát, nếu bạn tạo một đối tượng Text từ một chuỗi ký tự.

Lưu ý rằng điều này cũng sẽ xảy ra nếu bạn tạo nó từ một char[] tạo ra trên stack:

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

như Foo bây giờ sẽ cố gắng delete một chồng đối tượng.

Một trường hợp này có thể xảy ra là nếu bạn kích đúp xóa một đối tượng:

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

Cảm ơn, tôi đã giải quyết vấn đề thay đổi mọi char * thành std :: string, bởi vì nó đã gây ra rò rỉ bộ nhớ và các vấn đề khác. –

Các vấn đề liên quan