c++新崩溃仅在发布版(MSVS10)

c++ new crashing in release only (MSVS10)

本文关键字:布版 MSVS10 崩溃 c++ 新崩溃      更新时间:2023-10-16

仅运行发行版可执行文件时(在visual studio中运行时不会出现问题),我的程序崩溃。当使用"附加到进程"功能时,visual studio指示以下功能发生崩溃:

World::blockmap World::newBlankBlockmap(int sideLen, int h){
    cout << "newBlankBlockmap side: "<<std::to_string((long long)sideLen) << endl;
    cout << "newBlankBlockmap height: "<<std::to_string((long long)h) << endl;
    short*** bm = new short**[sideLen];
    for(int i=0;i<sideLen;i++){
        bm[i] = new short*[h];
        for(int j=0;j<h;j++){
            bm[i][j] = new short[sideLen];
            for (int k = 0; k < sideLen ; k++)
            {
                bm[i][j][k] = blocks->getAIR_BLOCK();
            }
        }
    }
    return (blockmap)bm;
}

这是从一个儿童班上叫的。。。

World::chunk* World_E::newChunkMap(World::floatmap north, World::floatmap east, World::floatmap south, World::floatmap west
,float lowlow, float highlow, float highhigh, float lowhigh, bool displaceSides){
    World::chunk* c = newChunk(World::CHUNK_SIZE+1,World::HEIGHT);
    for (int i = 0; i < World::CHUNK_SIZE ; i++)
    {
        for (int k = 0; k < World::CHUNK_SIZE ; k++)
        {
            c->bm[i][0][k] = blocks->getDUMMY_BLOCK();
        }
    }
    c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    return c;

}

在哪里。。。

class World {
public: typedef short*** blockmap;
...

VS指向的线是…

short*** bm = new short**[sideLen];

"附加到进程"函数统计本地变量是。。。sideLen=1911407648h=0这是我没有预料到的,但cout分别输出9和30,这是意料之中的。

我知道大多数"仅发布时崩溃"的问题都是由于未初始化的变量造成的,然而,我在这里没有看到相关的问题。

我得到的唯一错误信息是。。。Windows在Blocks Project.exe中触发了一个断点。这可能是由于堆损坏所致

我被这个问题难住了,错在哪里?如何更好地调试发行版可执行文件?

如果需要的话,我可以发布更多的代码,但是,请记住有很多代码

提前谢谢。

"我没有看到从第二块代码调用的World::newBlankBlockmap()。——Michael Burr",我忘了那一点,给你。。。

World::chunk* World::newChunk(int side, int height){
cout << "newChunk side: "<<std::to_string((long long)side) << endl;
cout << "newChunk height: "<<std::to_string((long long)height) << endl;
chunk* ch = new chunk();
ch->bm = newBlankBlockmap(side,height);
ch->fm = newBlankFloatmap(side);
return ch;

}

在哪里。。。

struct chunk {
    blockmap bm;
    floatmap fm;
};

如世界级中定义的

重申评论的含义:从你发布的内容来看,你的代码结构似乎很糟糕。像short***这样的三指针结构几乎不可能调试,应该不惜一切代价避免。您收到的堆损坏错误消息表明您的代码中有一个错误的内存访问,这在当前设置中是不可能自动找到的。

在这一点上,您唯一的选择是手动挖掘整个代码,直到发现错误,或者开始重构。后者现在看起来可能更耗时,但如果您计划在未来使用此代码,则不会如此。

考虑以下可能的重构提示:

  • 不要使用普通数组来存储值。std::vector同样有效,而且更容易调试
  • 避免使用普通newdelete。在使用STL容器和智能指针的现代C++中,纯内存分配应该只在极少数的特殊情况下发生
  • 始终对阵列访问操作进行范围检查。如果您担心性能问题,请使用在发布版本中消失的断言,但请确保在调试需要检查时,检查就在那里
  • 在C++中建模三维数组可能很棘手,因为operator[]只提供对一维数组的支持。一个很好的折衷方案是使用operator(),它可以采用任意数量的索引
  • 避免C样式强制转换。它们可能非常不可预测。请改用C++强制转换static_castdynamic_castreinterpret_cast。如果你发现自己经常使用reinterpret_cast,那么你的设计可能在某个地方出错了

此行short*** bm = new short**[sideLen];中存在问题。存储器被分配给sideLen元件,但是分配线bm[i][j][k] = blocks->getAIR_BLOCK();需要具有大小sideLen * sideLen * h的阵列。为了解决这个问题,需要将第1行更改为short*** bm = new short**[sideLen * sideLen * h];