我正在尝试创建一个可以渲染网格物体的路径跟踪器,但是在尝试构建一个简单的边界体积层次结构时遇到了问题,这将有助于我遍历网格物体并提高性能。但是,我遇到一个问题,每当我尝试递归地将网格中的顶点划分(我猜最终要构建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);
}
您将100,000个浮点数推入numbers
,然后在其上调用Partition()
。 Partition()
一次又一次地调用双方的Partition()
(直到Numbers
小于4
仍需要一段时间)。您只是通过重复太多次而使调用堆栈溢出。
附带说明:停止像这样使用new
。
在函数Partition
中,您递归调用Partition
:
LeftNode->Partition();
RightNode->Partition();
无限地不需要return
(return
中没有Partition
语句)。每当您使用C ++调用函数时,返回地址(和任何参数)都被压入堆栈。 C ++堆栈大小从几千字节到几兆字节不等,但并不是真正为深度递归而设计的。因此,即使您停止无限递归(使用某种if
... return;
),您也不想递归调用Partition
100,000次。也许将其重构为循环?