# Как устранить утечку памяти в рекурсии?

``````#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:
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) {
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]{
});
}

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);
}

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 });
//delete[] p1, p2, p3;
}

void generate(float x, float y, float z) {
cameraPosition = FloatArray(new float[3]{ x,y,z });
existChunksId.clear();

// for(int i = 0; i<8;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;
}``````

Ко всем new есть соответствующие delete[], но с ними очищается только половина памяти (с имеющимися параметрами в generate: без delete[] съедает больше 400 МБ, с delete[] - 210.
Использую VS C++ 2015
• Вопрос задан
• 325 просмотров
Решения вопроса 1
1) Использовать умные указатели.
2) Если рекурсия глубокая, то эту память может отжирать стек, а не куча.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

### Войдите, чтобы написать ответ

Похожие вопросы
от 200 000 до 300 000 ₽
29 янв. 2022, в 17:08
40000 руб./за проект
29 янв. 2022, в 16:50
3000 руб./за проект
29 янв. 2022, в 16:11
700 руб./в час