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