内存泄漏问题

问题描述 投票:1回答:2

我正在尝试创建一个可以渲染网格物体的路径跟踪器,但是在尝试构建一个简单的边界体积层次结构时遇到了问题,这将有助于我遍历网格物体并提高性能。但是,我遇到一个问题,每当我尝试递归地将网格中的顶点划分(我猜最终要构建bvh)时,都会导致内存泄漏,并链接到cpp文件“ new_scalar.cpp”,告诉我有堆栈溢出。

为了解决该问题,我创建了另一个项目,在该项目中,我有一个节点,该节点存储一个浮点向量,每当我调用分区时,它都会创建两个新节点,每个节点的拆分向量的一半类似于递归性质建立bvh。然后,我在尝试修复该问题时遇到了同样的问题,但我不明白为什么。

#include <iostream>
#include <vector>
#include <ctime>

#define print(x) std::cout << x << std::endl;

struct Node {
    std::vector<float*> Numbers;

    Node* LeftNode;
    Node* RightNode;

    void Partition() {
        if (Numbers.size() > 4) {
            // Find center
            float min = HUGE_VALF;
            float max = -HUGE_VALF;

            for (int i = 0; i < Numbers.size(); i++) {
                min = fmin(min, *Numbers[i]);
                max = fmax(max, *Numbers[i]);
            }

            float center = (min + max) * 0.5f;

            // Partitioning
            LeftNode = new Node;
            RightNode = new Node;

            for (int i = 0; i < Numbers.size(); i++) {
                if (*Numbers[i] < center) {
                    LeftNode->Numbers.push_back(Numbers[i]);
                }
                else {
                    RightNode->Numbers.push_back(Numbers[i]);
                }
            }

            LeftNode->Partition();
            RightNode->Partition();
        }
    }
};

struct Object {
    Node* Root;

    void BuildBVH(std::vector<float*> numbers) {
        Root = new Node;
        Root->Numbers = numbers;
        Root->Partition();
    }
};

int main()
{
    srand(std::clock());


    // Initialize vector
    std::vector<float*> numbers;

    for (int i = 0; i < 100000; i++) {
        float* newNumber = new float;
        *newNumber = ((float)(rand() % 1000000) / 1000000.0f) * 2.0f - 1.0f;

        numbers.push_back(newNumber);
    }


    Object object;
    object.BuildBVH(numbers);
}
c++ visual-c++ raytracing
2个回答
0
投票

您将100,000个浮点数推入numbers,然后在其上调用Partition()Partition()一次又一次地调用双方的Partition()(直到Numbers小于4仍需要一段时间)。您只是通过重复太多次而使调用堆栈溢出。

附带说明:停止像这样使用new


0
投票

在函数Partition中,您递归调用Partition

 LeftNode->Partition();
 RightNode->Partition();

无限地不需要returnreturn中没有Partition语句)。每当您使用C ++调用函数时,返回地址(和任何参数)都被压入堆栈。 C ++堆栈大小从几千字节到几兆字节不等,但并不是真正为深度递归而设计的。因此,即使您停止无限递归(使用某种if ... return;),您也不想递归调用Partition 100,000次。也许将其重构为循环?

© www.soinside.com 2019 - 2024. All rights reserved.