From b681690807f1fc56ba0c2f3e5b2af9da9ccd452d Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 16 Jan 2022 12:47:19 -0700 Subject: [PATCH] qbsp: fix some memory leaks --- include/qbsp/surfaces.hh | 1 + qbsp/qbsp.cc | 1 + qbsp/surfaces.cc | 20 ++++++++++++++++++++ qbsp/writebsp.cc | 13 ++----------- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/include/qbsp/surfaces.hh b/include/qbsp/surfaces.hh index fe41f872..077003a9 100644 --- a/include/qbsp/surfaces.hh +++ b/include/qbsp/surfaces.hh @@ -22,3 +22,4 @@ #pragma once surface_t *GatherNodeFaces(node_t *headnode); +void FreeNodes(node_t* node); diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 9d7c023f..7bbe5459 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -697,6 +697,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) } FreeBrushes(entity); + FreeNodes(nodes); } /* diff --git a/qbsp/surfaces.cc b/qbsp/surfaces.cc index d445f5df..865a6ea1 100644 --- a/qbsp/surfaces.cc +++ b/qbsp/surfaces.cc @@ -118,12 +118,30 @@ void SubdivideFace(face_t *f, face_t **prevptr) static void FreeNode(node_t* node) { + if (node->faces) { + face_t *f, *next; + for (f = node->faces; f; f = next) { + next = f->next; + delete f; + } + node->faces = nullptr; + } if (node->markfaces) { delete[] node->markfaces; + node->markfaces = nullptr; } delete node; } +void FreeNodes(node_t* node) +{ + if (node->planenum != PLANENUM_LEAF) { + FreeNodes(node->children[0]); + FreeNodes(node->children[1]); + } + FreeNode(node); +} + /* ============================================================================= GatherNodeFaces @@ -148,6 +166,8 @@ static void GatherNodeFaces_r(node_t *node, std::map &planefaces) planefaces[f->planenum] = f; } } + // don't attempt to free node->faces again as ownership has moved to the planefaces map + node->faces = nullptr; GatherNodeFaces_r(node->children[0], planefaces); GatherNodeFaces_r(node->children[1], planefaces); } diff --git a/qbsp/writebsp.cc b/qbsp/writebsp.cc index 33d439a3..8a129e41 100644 --- a/qbsp/writebsp.cc +++ b/qbsp/writebsp.cc @@ -108,11 +108,8 @@ static size_t ExportClipNodes(mapentity_t *entity, node_t *node) { face_t *face, *next; - // FIXME: free more stuff? if (node->planenum == PLANENUM_LEAF) { - int contents = node->contents.native; - delete node; - return contents; + return node->contents.native; } /* emit a clipnode */ @@ -128,12 +125,6 @@ static size_t ExportClipNodes(mapentity_t *entity, node_t *node) clipnode.children[0] = child0; clipnode.children[1] = child1; - for (face = node->faces; face; face = next) { - next = face->next; - delete face; - } - - delete node; return nodenum; } @@ -142,7 +133,7 @@ static size_t ExportClipNodes(mapentity_t *entity, node_t *node) ExportClipNodes Called after the clipping hull is completed. Generates a disk format -representation and frees the original memory. +representation. This gets real ugly. Gets called twice per entity, once for each clip hull. First time just store away data, second time fix up reference points to