C++ 奇怪的堆损坏错误
我从Visual C++中获取此eror: HEAP[ShockRay3.exe]:00557018处的堆块在00557044处修改,超过了请求的大小24 当我在函数中的两个递归调用之间添加一行代码时,就会发生这种情况。这行代码所做的只是更改一个指针,但由于某种原因,每次我把它放进去,都会出现这个错误 这是代码的简化版本(函数调用时仅使用堆内存)C++ 奇怪的堆损坏错误,c++,c,C++,C,我从Visual C++中获取此eror: HEAP[ShockRay3.exe]:00557018处的堆块在00557044处修改,超过了请求的大小24 当我在函数中的两个递归调用之间添加一行代码时,就会发生这种情况。这行代码所做的只是更改一个指针,但由于某种原因,每次我把它放进去,都会出现这个错误 这是代码的简化版本(函数调用时仅使用堆内存) 但在此之前,调用堆栈中的行似乎是导致这种情况的原因。我不知道更改指针如何将代码跳转到删除行。我看不出您发布的代码中有任何明显的错误,但是一些省略的代码
但在此之前,调用堆栈中的行似乎是导致这种情况的原因。我不知道更改指针如何将代码跳转到删除行。我看不出您发布的代码中有任何明显的错误,但是一些省略的代码可能与此相关。因此,这里有一些想法需要调查:
- 是否正确计算了
和leftCount
,以便它们不会超出列表rightCount
和leftList
是否正确填充了有效指针rightList
- 无论从外部世界在哪里调用
,第二个和第三个参数是否有效和正确BuildBranch
- 外界是否期望该函数删除第二个参数
- 当崩溃发生时,函数自身递归了多少次?它是发生在最初还是在内心深处
- 是否可以对递归调用重新排序,以便先处理右框,然后再处理左框?如果是这样的话,当您尝试这样做时,崩溃发生在哪一个范围内
- 将崩溃样本减少到最低程度——在您的情况下,将使其崩溃的数据加载到KDTree中
- 使用后的空指针——至少用于测试目的
- 使用断言——在每次指针取消引用之前断言不为null
- 学习如何使用编译器调试器,并逐步通过最小大小的示例,特别是仔细查看
曲线框
你可以试试。它非常擅长发现内存覆盖和相关问题
- 寻找虫子可能需要几天(甚至几夜!)。在这么大的一大块代码中,很难找到它,而且您发布的内容本身也没有bug。发布整个代码也不会有帮助,因为如果没有类的其他部分,我们就必须重新实现它来测试它
然而,我能做的是给你一些建议:
下面是关于应用程序验证程序的一点重要信息。您可以设置验证。如果您的应用程序有任何堆溢出或不足,它将立即被捕获。而且它非常容易使用。而且是免费的 更改指针不会跳转到任何地方。更改指针后,立即对同一个函数进行递归调用,导致崩溃。这就是为什么您会在调用堆栈中看到崩溃上方的那一行,这是应该的。至于崩溃,您代码的功能显然取决于当前的
curVoxelBounds
值。您的实现包含一个bug(很可能是数组溢出),只有在您更改该指针时才会暴露出来。这就是问题的全部。我仍然不确定为什么会导致数组溢出。然后试着找出原因?毕竟,如果你有一个bug,那么在某种程度上你不知道你的代码实际上在做什么(与你打算它做什么相反)。@Stewart:我也“不确定”。您没有提供任何代码来显示数组是如何填充的。我同意,请使用调试器。VisualStudio有一个很棒的。这是一件特别难调试的事情,但是如果你仔细检查一下,也许你会发现一些有趣的事情是的,我很确定它在省略的代码中的某个地方。谢谢
int KDTree::BuildBranch(int height, Mailbox** objs, int nObjects)
{
{...}
//Check for termination
if(height == -1 || nObjects < minObjectsPerNode)
{
{...}
return nodeIndex - 1;
}
//Save this node's index and increment the current index to save space for this node
BoundingBox* tempBox = new BoundingBox();
//If this is first voxel, we don't keep track of stradle counts
if(nodeIndex == 1)
{
{...}
for(int i = 0; i < nObjects; i++)
{
//Get bounding box
objs[i]->prim->MakeBoundingBox(tempBox);
//Add mins to split lists
xMins[index] = tempBox->x0;
yMins[index] = tempBox->y0;
zMins[index] = tempBox->z0;
//Add maxs
xMaxs[index] = tempBox->x1;
yMaxs[index] = tempBox->y1;
zMaxs[index] = tempBox->z1;
index++;
}
}
else
{
for(int i = 0; i < nObjects; i++)
{
//Get bounding box
objs[i]->prim->MakeBoundingBox(tempBox);
//Add mins to split lists checking for straddle
if(tempBox->x0 < curVoxelBounds->x0)
{
{...}
}
else
{
xMins[xMinCount] = tempBox->x0;
{...}
}
if(tempBox->y0 < curVoxelBounds->y0)
{
{...}
}
else
{
yMins[yMinCount] = tempBox->y0;
{...}
}
if(tempBox->z0 < curVoxelBounds->z0)
{
{...}
}
else
{
zMins[zMinCount] = tempBox->z0;
{...}
}
//Add maxs to split lists checking for straddle
if(tempBox->x1 > curVoxelBounds->x1)
{
{...}
}
else
{
xMaxs[xMaxCount] = tempBox->x1;
{...}
}
if(tempBox->y1 > curVoxelBounds->y1)
{
{...}
}
else
{
yMaxs[yMaxCount] = tempBox->y1;
{...}
}
if(tempBox->z1 > curVoxelBounds->z1)
{
{...}
}
else
{
zMaxs[zMaxCount] = tempBox->z1;
{...}
}
}
}
//If this is the root node, construct the scene bounding box
if(nodeIndex == 1)
{
bb = new BoundingBox(xMins[0], xMaxs[nObjects - 1], yMins[0], yMaxs[nObjects - 1], zMins[0], zMaxs[nObjects - 1]);
curVoxelBounds = new BoundingBox(xMins[0], xMaxs[nObjects - 1], yMins[0], yMaxs[nObjects - 1], zMins[0], zMaxs[nObjects - 1]);
}
{...}
//Allocate space for left and right lists
Mailbox** leftList = new Mailbox*[minLeftCounter];
Mailbox** rightList = new Mailbox*[minRightCounter];
//Sort objects into lists of those to the left and right of the split plane
//Bounding box for left and right
BoundingBox* rightBox = NULL;
BoundingBox* leftBox = NULL;
//Saved pointer to current bounding box
BoundingBox* savedBox = curVoxelBounds;
int leftIndex = 0, rightIndex = 0;
{...}
switch(axis)
{
case 0:
for(int i = 0; i < nObjects; i++)
{
//Get object bounding box
objs[i]->prim->MakeBoundingBox(tempBox);
//Add to left and right lists when necessary
if(tempBox->x0 < splitLoc)
{
{...}
}
if(tempBox->x1 > splitLoc)
{
{...}
}
}
//Construct new bounding boxes
leftBox = new BoundingBox(curVoxelBounds->x0, splitLoc, curVoxelBounds->y0,
curVoxelBounds->y1, curVoxelBounds->z0, curVoxelBounds->z1);
rightBox = new BoundingBox(splitLoc, curVoxelBounds->x1, curVoxelBounds->y0,
curVoxelBounds->y1, curVoxelBounds->z0, curVoxelBounds->z1);
break;
case 1:
for(int i = 0; i < nObjects; i++)
{
//Get object bounding box
objs[i]->prim->MakeBoundingBox(tempBox);
//Add to left and right lists when necessary
if(tempBox->y0 < splitLoc)
{
{...}
}
if(tempBox->y1 > splitLoc)
{
{...}
}
}
//Construct new bounding boxes
leftBox = new BoundingBox(curVoxelBounds->x0, curVoxelBounds->x1, curVoxelBounds->y0,
splitLoc, curVoxelBounds->z0, curVoxelBounds->z1);
rightBox = new BoundingBox(curVoxelBounds->x0, curVoxelBounds->x1, splitLoc,
curVoxelBounds->y1, curVoxelBounds->z0, curVoxelBounds->z1);
break;
case 2:
for(int i = 0; i < nObjects; i++)
{
//Get object bounding box
objs[i]->prim->MakeBoundingBox(tempBox);
//Add to left and right lists when necessary
if(tempBox->z0 < splitLoc)
{
{...}
}
if(tempBox->z1 > splitLoc)
{
{...}
}
}
//Construct new bounding boxes
leftBox = new BoundingBox(curVoxelBounds->x0, curVoxelBounds->x1, curVoxelBounds->y0,
curVoxelBounds->y1, curVoxelBounds->z0, splitLoc);
rightBox = new BoundingBox(curVoxelBounds->x0, curVoxelBounds->x1, curVoxelBounds->y0,
curVoxelBounds->y1, splitLoc, curVoxelBounds->z1);
break;
};
//Delete the bounding box
delete tempBox;
//Delete old objects array
delete[] objs;
{...}
//Change bounding box
curVoxelBounds = leftBox;
//Build the left branch
BuildBranch(height - 1, leftList, leftCount);
//Change bounding box
curVoxelBounds = rightBox; //<----THIS IS THE LINE RESULTING IN THE ERROR
//Build the right branch
int rcNodeIndex = BuildBranch(height - 1, rightList, rightCount);
//Restore bounding box
curVoxelBounds = savedBox;
//Delete left and right bounding boxes
delete leftBox;
delete rightBox;
{...}
return thisNodeIndex;
}
delete[] objs;