【问题标题】:_Block_Type_Is_Valid (pHead->nBlockUse) Error_Block_Type_Is_Valid (pHead->nBlockUse) 错误
【发布时间】:2011-09-17 20:38:07
【问题描述】:

我一直在从事一个新项目,但遇到了一个我不知道为什么会失败的问题。

当我执行此行删除 textY 时,给我错误 _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;
}

字体.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

字体.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 时,我使用了复制构造函数,因此不同的指针可以毫无问题地复制。

【问题讨论】:

标签: c++ debugging visual-c++ pointers sdl


【解决方案1】:

只需使用std::string。这个错误意味着你双重删除了一些东西,或者类似的东西,如果你不管理自己的记忆,你就不会遇到这个问题。您的代码充满了内存泄漏和其他 std::string 不会出现的错误。

【讨论】:

  • 感谢您的帮助。我更改了 std::string 的所有 char* 并且没有问题地工作。如果我问,如果在 STL 容器中使用原始指针有问题,我想在其中一些容器中使用 auto_ptr,在其他需要它的对象中使用 shared_ptr,这真的有必要吗?
  • @oscar.rpr:您不能在标准容器中使用auto_ptr。这个问题将在 C++11 中修复,但在 C++03 中,您必须使用 shared_ptr- 即使只有一个引用。
  • 感谢您的帮助,所以我将在 STL 容器中使用 shared_ptr 而不是原始指针。
  • “如果您不管理自己的内存就不会遇到的问题”我讨厌在垃圾收集器和更难以调试的引用计数的世界中的这种情绪。确定 string 是一个特例,但这里的正确答案是“如果你正确管理你的内存,你就不会遇到这个问题”。
  • @jheriko:垃圾收集器和引用计数与 std::string/std::vector 之间存在天壤之别。不要手动管理自己的内存。这只会导致无限错误。
【解决方案2】:

据我所知,该错误与 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");
}

C++03(为了向后兼容...)允许文字字符串 ("hi") 绑定到非 const char* 指针,如本代码所示。谢天谢地,C++11 修复了这个问题,这实际上应该不再编译。现在,删除文字字符串显然不起作用,因为该字符串被放置在 .exe 的只读部分中,因此不是deleteable。如果您从文字字符串实例化 Text 对象,我想这就是您的错误的来源。

请注意,如果您从堆栈上创建的 char[] 创建它,也会发生这种情况:

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

因为Foo 现在将尝试delete 堆栈对象。

另一种可能发生这种情况的情况是,如果您双重删除一个对象:

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

【讨论】:

  • 谢谢,我已经解决了将每个 char * 更改为 std::string 的问题,因为它会导致内存泄漏和其他问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-31
  • 1970-01-01
  • 2015-02-11
  • 2015-09-22
  • 2013-11-10
  • 1970-01-01
相关资源
最近更新 更多