内存泄漏问题

时间:2019-11-05 11:36:54

标签: c++ visual-c++ raytracing

我正在尝试创建一个可以渲染网格的路径跟踪器,但是在尝试构建一个幼稚的边界体积层次结构时遇到了一个问题,这将有助于我遍历网格并提高性能。但是,我遇到一个问题,每当我尝试递归地将网格中的顶点划分(我猜最终要构建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);
}

2 个答案:

答案 0 :(得分:2)

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

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

每当您使用C ++调用一个函数时,返回地址(和任何参数)都会被压入堆栈。 C ++堆栈大小从几千字节到几兆字节不等,但并不是真正为深度递归而设计的。因此,您不想递归调用Partition 100,000次。也许将其重构为循环?

答案 1 :(得分:1)

您将100,000个浮点数推入numbers,然后在其中调用Partition()Partition()一遍又一遍地调用Partition()到双方(直到Numbers小于4为止仍需要一段时间)。您只会重复执行太多次而导致调用堆栈溢出。

旁注:停止像这样使用new