Answer the question
In order to leave comments, you need to log in
How to fix memory leak in recursion?
#include <inttypes.h>
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <vector>
#include <iostream>
#include <memory>
#include <time.h>
struct ChunkId {
int low;
int high;
};
using FloatArray = float*;// std::unique_ptr<float[]>;
class OctaTerrain {
private:
float RADIUS;
int MAX_Z;
float DETAIL_LEVEL;
std::vector<int64_t> existChunksId;
std::vector<float*> existChunksVertices;
FloatArray cameraPosition;
float theta = M_PI / 2;
float phi = M_PI / 2;
public:
OctaTerrain(float radius, int max_z, float detail) {
RADIUS = radius;
MAX_Z = max_z;
DETAIL_LEVEL = detail;
cameraPosition = FloatArray(new float[3]{ RADIUS,0,0 });
}
FloatArray toPoint(float lat, float lon) {
return FloatArray(new float[3]{
RADIUS * (float)cos(lat) * (float)sin(lon),
RADIUS * (float)sin(lat),
RADIUS * (float)cos(lat) * (float)cos(lon)
});
}
float distance(FloatArray &a, FloatArray &b) {
return sqrt(pow(a[0] - b[0], 2) + pow(a[1] - b[1], 2) + pow(a[2] - b[2], 2));
}
bool needDivide(FloatArray &v1, FloatArray &coords, int z) {
FloatArray v2 = toPoint(coords[0], coords[1]);
if (distance(v1, v2) < pow(DETAIL_LEVEL / z, 2)) {
delete[] v2;
return true;
}
delete[] v2;
return false;
}
FloatArray getChunkCenter(FloatArray &p1, FloatArray &p2, FloatArray &p3) {
return FloatArray(new float[2]{ (p1[0] + p2[0] + p3[0]) / 3,(p1[1] + p2[1] + p3[1]) / 3 });
}
/*
int64_t increaseIdLevel(int64_t id) {
return id + ((int64_t)0x1 << 7 * 8);
}
int getIdLevel(int64_t id) {
return id >> 7 * 8;
}
int64_t setIdSide(int side) {
return (int64_t)side << 6 * 8;
}
int getIdSide(int64_t id) {
return (id >> 6 * 8) & 0xffff;
}
int64_t setIdIndex(int64_t id, int index) {
return id | ((int64_t)index << getIdLevel(id) * 2);
}
*/
int k = 0;
void addChunk(FloatArray &p1, FloatArray &p2, FloatArray &p3, int z){//int64_t id) {
//int z = getIdLevel(id);
FloatArray center = getChunkCenter(p1, p2, p3);
if (z < MAX_Z && needDivide(cameraPosition, center, z)) {
FloatArray p12(new float[2]{ (p1[0] + p2[0]) / 2,(p1[1] + p2[1]) / 2 });
FloatArray p23(new float[2]{ (p2[0] + p3[0]) / 2,(p2[1] + p3[1]) / 2 });
FloatArray p31(new float[2]{ (p1[0] + p2[0]) / 2,p1[0] == M_PI ? p3[1] : (p3[1] + p1[1]) / 2 });
// Align the longitude of the right side along the edge for the upper triangles
//id = increaseIdLevel(id);
z++;
addChunk(p1, p12, p31, z);// setIdIndex(id, 0));
addChunk(p12, p23, p31, z);// setIdIndex(id, 1));
addChunk(p12, p2, p23, z);// setIdIndex(id, 2));
addChunk(p31, p23, p3, z);// setIdIndex(id, 3));
//delete[] center,p12,p23,p31;
return;
}
//delete[] center;
k++;
// existChunksId.push_back(id);
}
void addSide(int id) {
float latScalar = (id>3 ? -1 : 1);
float lonScalar = id % 4;
FloatArray p1(new float[2]{ latScalar*theta, lonScalar*phi });
FloatArray p2(new float[2]{ 0.0,lonScalar*phi });
FloatArray p3(new float[2]{ 0.0,(lonScalar + 1)*phi });
addChunk(p1, p2, p3, 0);// setIdSide(id));
//delete[] p1, p2, p3;
}
void generate(float x, float y, float z) {
cameraPosition = FloatArray(new float[3]{ x,y,z });
existChunksId.clear();
addSide(1);
// addSide(1);
// for(int i = 0; i<8;i++)
// addSide(i);
printf("%d", k);// existChunksId.size());
}
std::vector<ChunkId> getIds() {
std::vector<ChunkId> v;
// std::sort(existChunksId.begin(), existChunksId.end());
for (const int64_t& i : existChunksId) {
ChunkId chunk;
chunk.high = i >> 32;
chunk.low = i & 0xffffffff;
v.push_back(chunk);
}
return v;
}
};
int main() {
auto terrain = new OctaTerrain(1,20,1);
time_t start, end;
time(&start);
terrain->generate(1.002,0,0);
time(&end);
double dif = difftime(end, start);
printf("\n%lf\n", dif);
std::cin.get();
return 0;
}
Answer the question
In order to leave comments, you need to log in
1) Use smart pointers.
2) If the recursion is deep, then this memory can be eaten by the stack, not the heap.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question