C++ 为什么free()让我的程序陷入困境?

C++ 为什么free()让我的程序陷入困境?,c++,c,C++,C,我使用free来释放在递归函数中为一组临时数组分配的内存。我会发布代码,但它相当长。当我注释掉这些free()调用时,程序运行不到一秒钟。但是,当我使用它们时,程序运行大约需要20秒。为什么会发生这种情况,如何解决?这大约是100 MB,所以我不想让内存泄漏 此外,当我运行包含所有启用了分析功能的free()调用的程序时,它会在不到一秒钟的时间内运行。我不知道这会有什么影响,但确实如此 在只使用了一些free()调用之后,似乎有一些特别的调用会导致程序速度减慢。其余的似乎没有效果 好的。。。以下

我使用free来释放在递归函数中为一组临时数组分配的内存。我会发布代码,但它相当长。当我注释掉这些free()调用时,程序运行不到一秒钟。但是,当我使用它们时,程序运行大约需要20秒。为什么会发生这种情况,如何解决?这大约是100 MB,所以我不想让内存泄漏

此外,当我运行包含所有启用了分析功能的free()调用的程序时,它会在不到一秒钟的时间内运行。我不知道这会有什么影响,但确实如此

在只使用了一些free()调用之后,似乎有一些特别的调用会导致程序速度减慢。其余的似乎没有效果

好的。。。以下是所需的代码:

void KDTree::BuildBranch(int height, Mailbox** objs, int nObjects)
{
int dnObjects = nObjects * 2;
int dnmoObjects = dnObjects - 1;

//Check for termination
if(height == -1 || nObjects < minObjectsPerNode)
{
    //Create leaf
    tree[nodeIndex] = KDTreeNode();

    if(nObjects == 1)
        tree[nodeIndex].InitializeLeaf(objs[0], 1);
    else
        tree[nodeIndex].InitializeLeaf(objs, nObjects);

    //Added a node, increment index
    nodeIndex++;

    return;
}

//Save this node's index and increment the current index to save space for this node
int thisNodeIndex = nodeIndex;
nodeIndex++;

//Allocate memory for split options
float* xMins = (float*)malloc(nObjects * sizeof(float));
float* yMins = (float*)malloc(nObjects * sizeof(float));
float* zMins = (float*)malloc(nObjects * sizeof(float));
float* xMaxs = (float*)malloc(nObjects * sizeof(float));
float* yMaxs = (float*)malloc(nObjects * sizeof(float));
float* zMaxs = (float*)malloc(nObjects * sizeof(float));

//Find all possible split locations
int index = 0;
BoundingBox* tempBox = new BoundingBox();
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++;
}

//Sort lists
Util::sortFloats(xMins, nObjects);
Util::sortFloats(yMins, nObjects);
Util::sortFloats(zMins, nObjects);
Util::sortFloats(xMaxs, nObjects);
Util::sortFloats(yMaxs, nObjects);
Util::sortFloats(zMaxs, nObjects);

//Allocate bin lists
Bin* xLeft = (Bin*)malloc(dnObjects * sizeof(Bin));
Bin* xRight = (Bin*)malloc(dnObjects * sizeof(Bin));
Bin* yLeft = (Bin*)malloc(dnObjects * sizeof(Bin));
Bin* yRight = (Bin*)malloc(dnObjects * sizeof(Bin));
Bin* zLeft = (Bin*)malloc(dnObjects * sizeof(Bin));
Bin* zRight = (Bin*)malloc(dnObjects * sizeof(Bin));

//Initialize all bins
for(int i = 0; i < dnObjects; i++)
{
    xLeft[i] = Bin(0, 0.0f);
    xRight[i] = Bin(0, 0.0f);
    yLeft[i] = Bin(0, 0.0f);
    yRight[i] = Bin(0, 0.0f);
    zLeft[i] = Bin(0, 0.0f);
    zRight[i] = Bin(0, 0.0f);
}

//Construct min and max bins bins from split locations
//Merge min/max lists together for each axis
int minIndex = 0, maxIndex = 0;
for(int i = 0; i < dnObjects; i++)
{
    if(maxIndex == nObjects || (xMins[minIndex] <= xMaxs[maxIndex] && minIndex != nObjects))
    {
        //Add split location to both bin lists
        xLeft[i].rightEdge = xMins[minIndex];
        xRight[i].rightEdge = xMins[minIndex];
        //Add geometry to mins counter
        xLeft[i+1].objectBoundCounter++;

        minIndex++;
    }
    else
    {
        //Add split location to both bin lists
        xLeft[i].rightEdge = xMaxs[maxIndex];
        xRight[i].rightEdge = xMaxs[maxIndex];
        //Add geometry to maxs counter
        xRight[i].objectBoundCounter++;

        maxIndex++;
    }
}

//Repeat for y axis
minIndex = 0, maxIndex = 0;
for(int i = 0; i < dnObjects; i++)
{
    if(maxIndex == nObjects || (yMins[minIndex] <= yMaxs[maxIndex] && minIndex != nObjects))
    {
        //Add split location to both bin lists
        yLeft[i].rightEdge = yMins[minIndex];
        yRight[i].rightEdge = yMins[minIndex];
        //Add geometry to mins counter
        yLeft[i+1].objectBoundCounter++;

        minIndex++;
    }
    else
    {
        //Add split location to both bin lists
        yLeft[i].rightEdge = yMaxs[maxIndex];
        yRight[i].rightEdge = yMaxs[maxIndex];
        //Add geometry to maxs counter
        yRight[i].objectBoundCounter++;

        maxIndex++;
    }
}

//Repeat for z axis
minIndex = 0, maxIndex = 0;
for(int i = 0; i < dnObjects; i++)
{
    if(maxIndex == nObjects || (zMins[minIndex] <= zMaxs[maxIndex] && minIndex != nObjects))
    {
        //Add split location to both bin lists
        zLeft[i].rightEdge = zMins[minIndex];
        zRight[i].rightEdge = zMins[minIndex];
        //Add geometry to mins counter
        zLeft[i+1].objectBoundCounter++;

        minIndex++;
    }
    else
    {
        //Add split location to both bin lists
        zLeft[i].rightEdge = zMaxs[maxIndex];
        zRight[i].rightEdge = zMaxs[maxIndex];
        //Add geometry to maxs counter
        zRight[i].objectBoundCounter++;

        maxIndex++;
    }
}

//Free split memory
free(xMins);
free(xMaxs);
free(yMins);
free(yMaxs);
free(zMins);
free(zMaxs);

//PreCalcs
float voxelL = xRight[dnmoObjects].rightEdge - xLeft[0].rightEdge;
float voxelD = zRight[dnmoObjects].rightEdge - zLeft[0].rightEdge;
float voxelH = yRight[dnmoObjects].rightEdge - yLeft[0].rightEdge;

float voxelSA = 2.0f * voxelL * voxelD + 2.0f * voxelL * voxelH + 2.0f * voxelD * voxelH;

//Minimum cost preset to no split at all
float minCost = (float)nObjects;
float splitLoc;
int minLeftCounter = 0, minRightCounter = 0;
int axis = -1;

 //---------------------------------------------------------------------------------------------
//Check costs of x-axis split planes keeping track of derivative using
//the fact that there is a minimum point on the graph costs vs split location
//Since there is one object per split plane
int splitIndex = 1;
float lastCost = nObjects * voxelL;
float tempCost;
float lastSplit = xLeft[1].rightEdge;
int leftCount = xLeft[1].objectBoundCounter, rightCount = nObjects - xRight[1].objectBoundCounter;
int lastLO = 0, lastRO = nObjects;
//Keep looping while cost is decreasing
while(splitIndex < dnObjects)
{
    tempCost = leftCount * (xLeft[splitIndex].rightEdge - xLeft[0].rightEdge) + rightCount * (xLeft[dnmoObjects].rightEdge - xLeft[splitIndex].rightEdge);
    if(tempCost < lastCost)
    {
        lastCost = tempCost;
        lastSplit = xLeft[splitIndex].rightEdge;
        lastLO = leftCount;
        lastRO = rightCount;
    }

    //Update counters
    splitIndex++;
    leftCount += xLeft[splitIndex].objectBoundCounter;
    rightCount -= xRight[splitIndex].objectBoundCounter;
}

//Calculate full SAH cost
lastCost = ((lastLO * (2 * (lastSplit - xLeft[0].rightEdge) * voxelD + 2 * (lastSplit - xLeft[0].rightEdge) * voxelH + 2 * voxelD * voxelH)) + (lastRO * (2 * (xLeft[dnmoObjects].rightEdge - lastSplit) * voxelD + 2 * (xLeft[dnmoObjects].rightEdge - lastSplit) * voxelH + 2 * voxelD * voxelH))) / voxelSA;

if(lastCost < minCost)
{
    minCost = lastCost;
    splitLoc = lastSplit;
    minLeftCounter = lastLO;
    minRightCounter = lastRO;
    axis = 0;
}

//---------------------------------------------------------------------------------------------
//Repeat for y axis
splitIndex = 1;
lastCost = nObjects * voxelH;
lastSplit = yLeft[1].rightEdge;
leftCount = yLeft[1].objectBoundCounter;
rightCount = nObjects - yRight[1].objectBoundCounter;
lastLO = 0;
lastRO = nObjects;
//Keep looping while cost is decreasing
while(splitIndex < dnObjects)
{
    tempCost = leftCount * (yLeft[splitIndex].rightEdge - yLeft[0].rightEdge) + rightCount * (yLeft[dnmoObjects].rightEdge - yLeft[splitIndex].rightEdge);
    if(tempCost < lastCost)
    {
        lastCost = tempCost;
        lastSplit = yLeft[splitIndex].rightEdge;
        lastLO = leftCount;
        lastRO = rightCount;
    }

    //Update counters
    splitIndex++;
    leftCount += yLeft[splitIndex].objectBoundCounter;
    rightCount -= yRight[splitIndex].objectBoundCounter;
}

//Calculate full SAH cost
lastCost = ((lastLO * (2 * (lastSplit - yLeft[0].rightEdge) * voxelD + 2 * (lastSplit - yLeft[0].rightEdge) * voxelL + 2 * voxelD * voxelL)) + (lastRO * (2 * (yLeft[dnmoObjects].rightEdge - lastSplit) * voxelD + 2 * (yLeft[dnmoObjects].rightEdge - lastSplit) * voxelL + 2 * voxelD * voxelL))) / voxelSA;

if(lastCost < minCost)
{
    minCost = lastCost;
    splitLoc = lastSplit;
    minLeftCounter = lastLO;
    minRightCounter = lastRO;
    axis = 1;
}

//---------------------------------------------------------------------------------------------
//Repeat for z axis
splitIndex = 1;
lastCost = nObjects * voxelD;
lastSplit = zLeft[1].rightEdge;
leftCount = zLeft[1].objectBoundCounter;
rightCount = nObjects - zRight[1].objectBoundCounter;
lastLO = 0;
lastRO = nObjects;
//Keep looping while cost is decreasing
while(splitIndex < dnObjects)
{
    tempCost = leftCount * (zLeft[splitIndex].rightEdge - zLeft[0].rightEdge) + rightCount * (zLeft[dnmoObjects].rightEdge - zLeft[splitIndex].rightEdge);
    if(tempCost < lastCost)
    {
        lastCost = tempCost;
        lastSplit = zLeft[splitIndex].rightEdge;
        lastLO = leftCount;
        lastRO = rightCount;
    }

    //Update counters
    splitIndex++;
    leftCount += zLeft[splitIndex].objectBoundCounter;
    rightCount -= zRight[splitIndex].objectBoundCounter;
}

//Calculate full SAH cost
lastCost = ((lastLO * (2 * (lastSplit - zLeft[0].rightEdge) * voxelL + 2 * (lastSplit - zLeft[0].rightEdge) * voxelH + 2 * voxelH * voxelL)) + (lastRO * (2 * (zLeft[dnmoObjects].rightEdge - lastSplit) * voxelL + 2 * (zLeft[dnmoObjects].rightEdge - lastSplit) * voxelH + 2 * voxelH * voxelL))) / voxelSA;

if(lastCost < minCost)
{
    minCost = lastCost;
    splitLoc = lastSplit;
    minLeftCounter = lastLO;
    minRightCounter = lastRO;
    axis = 2;
}

//Free bin memory
free(xLeft);
free(xRight);
free(yLeft);
free(yRight);
free(zLeft);
free(zRight);

//---------------------------------------------------------------------------------------------
//Make sure a split is in our best interest
if(axis == -1)
{
    //If not decrement the node counter
    nodeIndex--;
    BuildBranch(-1, objs, nObjects);

    return;
}

//Allocate space for left and right lists
Mailbox** leftList = (Mailbox**)malloc(minLeftCounter * sizeof(void*));
Mailbox** rightList = (Mailbox**)malloc(minRightCounter * sizeof(void*));

//Sort objects into lists of those to the left and right of the split plane
int leftIndex = 0, rightIndex = 0;
leftCount = 0;
rightCount = 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)
        {
            leftList[leftIndex++] = objs[i];
            leftCount++;
        }

        if(tempBox->x1 > splitLoc)
        {
            rightList[rightIndex++] = objs[i];
            rightCount++;
        }
    }
    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)
        {
            leftList[leftIndex++] = objs[i];
            leftCount++;
        }

        if(tempBox->y1 > splitLoc)
        {
            rightList[rightIndex++] = objs[i];
            rightCount++;
        }

    }
    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)
        {
            leftList[leftIndex++] = objs[i];
            leftCount++;
        }

        if(tempBox->z1 > splitLoc)
        {
            rightList[rightIndex++] = objs[i];
            rightCount++;
        }

    }
    break;
};

//Delete the bounding box
delete tempBox;

//Delete old objects array
free(objs);

//Construct left and right branches
BuildBranch(height - 1, leftList, leftCount);
BuildBranch(height - 1, rightList, rightCount);

//Build this node
tree[thisNodeIndex] = KDTreeNode();
tree[thisNodeIndex].InitializeInterior(axis, splitLoc, nodeIndex - 1);

return;
}
void KDTree::BuildBranch(int高度,邮箱**objs,int nObjects)
{
int dnObjects=nObjects*2;
int dnmoObjects=dnObjects-1;
//检查是否终止
if(高度==-1 | | nObjectsprim->MakeBoundingBox(tempBox);
//将分钟添加到拆分列表
xMins[index]=tempBox->x0;
yMins[index]=tempBox->y0;
zMins[index]=tempBox->z0;
//添加最大值
xMaxs[index]=tempBox->x1;
yMaxs[index]=tempBox->y1;
zMaxs[index]=tempBox->z1;
索引++;
}
//排序列表
Util::sortFloats(xMins,nobject);
Util::sortFloats(yMins,nobject);
Util::sortFloats(zMins,nObjects);
Util::sortFloats(xMaxs,nObjects);
Util::sortFloats(yMaxs,nObjects);
Util::sortFloats(zmax,nObjects);
//分配垃圾箱列表
Bin*xLeft=(Bin*)malloc(dnObjects*sizeof(Bin));
Bin*xRight=(Bin*)malloc(dnObjects*sizeof(Bin));
Bin*yLeft=(Bin*)malloc(dnObjects*sizeof(Bin));
Bin*yRight=(Bin*)malloc(dnObjects*sizeof(Bin));
Bin*zLeft=(Bin*)malloc(dnObjects*sizeof(Bin));
Bin*zRight=(Bin*)malloc(dnObjects*sizeof(Bin));
//初始化所有垃圾箱
对于(int i=0;ix1>splitLoc)
{
rightList[rightIndex++]=objs[i];
rightCount++;
}
}
打破
案例1:
for(int i=0;iprim->MakeBoundingBox(tempBox);
//必要时添加到左侧和右侧列表
如果(临时框->y0y1>拆分位置)
{
rightList[rightIndex++]=objs[i];
rightCount++;
}
}
打破
案例2:
for(int i=0;iprim->MakeBoundingBox(tempBox);
//必要时添加到左侧和右侧列表
如果(临时框->z0z1>splitLoc)
{
rightList[rightIndex++]=objs[i];
rightCount++;
}
}
打破
};
//删除边界框
删除临时框;
//删除旧对象数组
免费(objs);
//构造左分支和右分支
BuildBranch(高度-1,leftList,leftCount);
BuildBranch(高度-1,rightList,rightCount);
//构建此节点
树[thisNodeIndex]=KDTreeNode();
树[thisNodeIndex]。初始化内部(axis,splitLoc,nodeIndex-1);
返回;
}
编辑:
好吧,我试着用new/delete替换malloc/free,但这对速度没有影响。我还发现只有xLeft/xRight数组上的free()似乎对执行时间有显著影响。我通过移动free()来消除这个问题在递归调用之后调用,尽管我不知道为什么这会产生影响,因为我看不到在原始位置for free()之后使用这些数组.至于我为什么要使用malloc…这个程序的某些部分使用缓存对齐内存,所以我一直在使用_aligned _malloc。虽然可能有一种方法可以让新的缓存对齐,但这是我知道的唯一方法。

可能只是CRT使用的堆管理器的行为。它可能正在更新免费列表,或者其他一些internal结构来管理内存


如果存在瓶颈,您可能应该重新检查程序如何分配和使用内存。

可能只是CRT使用的堆管理器的行为。它可能正在更新可用列表或其他内部结构来管理内存

您可能应该重新检查您的程序是如何运行的 BoundingBox* tempBox = new BoundingBox(); // .... //Delete the bounding box delete tempBox; Bin* xLeft = (Bin*)malloc(dnObjects * sizeof(Bin)); // .... free(xMins);
//Allocate memory for split options
float* xMins = (float*)malloc(nObjects * sizeof(float));
float* yMins = (float*)malloc(nObjects * sizeof(float));
float* zMins = (float*)malloc(nObjects * sizeof(float));
float* xMaxs = (float*)malloc(nObjects * sizeof(float));
float* yMaxs = (float*)malloc(nObjects * sizeof(float));
float* zMaxs = (float*)malloc(nObjects * sizeof(float));
...
free(xMins);
free(xMaxs);
free(yMins);
free(yMaxs);
free(zMins);
free(zMaxs);
free(xMins);
free(yMins);
free(zMins);
free(xMaxs);
free(yMaxs);
free(zMaxs);