仅运行发行版可执行文件时(在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
同样有效,而且更容易调试 - 避免使用普通
new
和delete
。在使用STL容器和智能指针的现代C++中,纯内存分配应该只在极少数的特殊情况下发生 - 始终对阵列访问操作进行范围检查。如果您担心性能问题,请使用在发布版本中消失的断言,但请确保在调试需要检查时,检查就在那里
- 在C++中建模三维数组可能很棘手,因为
operator[]
只提供对一维数组的支持。一个很好的折衷方案是使用operator()
,它可以采用任意数量的索引 - 避免C样式强制转换。它们可能非常不可预测。请改用C++强制转换
static_cast
、dynamic_cast
和reinterpret_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];
。