From a22e6e813efd7037bc54ab41c1dd6638314c1a5e Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Sun, 9 Mar 2014 17:52:36 +0100
Subject: [PATCH] Add method to properly clean-up and deallocate a HEAP data
 structure

This method only frees the HEAP memory if the internal heap is used.
When using the system heap, however, the HEAP data structure contains
a C-array of std::vectors, created by placement new.  Hence, before
freeing the memory, those vectors need to have their destructors
called.  Otherwise, their memory will leak.
---
 low/heaps.c | 30 ++++++++++++++++++++++++++++++
 low/heaps.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/low/heaps.c b/low/heaps.c
index 5f4a2c095..883cd1a62 100644
--- a/low/heaps.c
+++ b/low/heaps.c
@@ -231,6 +231,36 @@ HEAP *NS_PREFIX NewHeap (enum HeapType type, MEM size, void *buffer)
   return(theHeap);
 }
 
+/****************************************************************************/
+/** \brief Clean up and deallocate a heap structure
+
+   \param theHeap The heap to be deallocated
+
+   This method properly cleans up a HEAP data structure, and then frees the
+   memory.
+ */
+/****************************************************************************/
+
+
+
+void NS_PREFIX DisposeHeap (HEAP *theHeap)
+{
+  if (theHeap != NULL) {
+#if UG_USE_SYSTEM_HEAP
+    /* When using the system heap, the HEAP data structure contains an array of
+     * std::vectors, which have all be created using placement new.  Therefore,
+     * before freeing the memory of a HEAP we have to call the destructors of
+     * these std::vectors explicitly.  Otherwise we get memory leaks.
+     */
+    using namespace std;
+    for (INT i=0; i<MARK_STACK_SIZE; i++)
+      theHeap->markedMemory[i].~vector<void*>();
+#endif
+  }
+
+  free(theHeap);
+}
+
 /****************************************************************************/
 /** \brief Allocate memory from heap, depending on heap type
 
diff --git a/low/heaps.h b/low/heaps.h
index 9bdef2e65..5c8c44e0c 100644
--- a/low/heaps.h
+++ b/low/heaps.h
@@ -212,6 +212,7 @@ INT          InitHeaps                (void);
 /** @name Functions for the simple and general heap management */
 /* @{ */
 HEAP        *NewHeap                (enum HeapType type, MEM size, void *buffer);
+void         DisposeHeap            (HEAP *theHeap);
 void        *GetMem                 (HEAP *theHeap, MEM n, HeapAllocMode mode);
 void            *GetMemUsingKey                 (HEAP *theHeap, MEM n, HeapAllocMode mode, INT key);
 void         DisposeMem             (HEAP *theHeap, void *buffer);
-- 
GitLab