Browse Source

[2088] Throw isc::OutOfRange when size passed to deallocate() is larger than what was allocated

Mukund Sivaraman 13 years ago
parent
commit
c0af8f8c45

+ 3 - 0
src/lib/util/memory_segment.h

@@ -43,6 +43,9 @@ public:
 
     /// \brief Free/release a segment of memory.
     ///
+    /// This method may throw <code>isc::OutOfRange</code> if \c size is
+    /// not equal to the originally allocated size.
+    ///
     /// \param ptr Pointer to the block of memory to free/release. This
     /// should be equal to a value returned by <code>allocate()</code>.
     /// \param size The size of the memory to be freed in bytes. This

+ 7 - 1
src/lib/util/memory_segment_local.cc

@@ -13,7 +13,8 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include "memory_segment_local.h"
-#include <new>
+#include <exceptions/exceptions.h>
+//#include <new>
 
 namespace isc {
 namespace util {
@@ -31,6 +32,11 @@ MemorySegmentLocal::allocate(size_t size) {
 
 void
 MemorySegmentLocal::deallocate(void* ptr, size_t size) {
+    if (size > allocated_size_) {
+      isc_throw(OutOfRange, "Invalid size to deallocate: " << size
+                << "; currently allocated size: " << allocated_size_);
+    }
+
     allocated_size_ -= size;
     free(ptr);
 }

+ 3 - 0
src/lib/util/memory_segment_local.h

@@ -48,6 +48,9 @@ public:
 
     /// \brief Free/release a segment of memory.
     ///
+    /// This method may throw <code>isc::OutOfRange</code> if \c size is
+    /// not equal to the originally allocated size.
+    ///
     /// \param ptr Pointer to the block of memory to free/release. This
     /// should be equal to a value returned by <code>allocate()</code>.
     /// \param size The size of the memory to be freed in bytes. This

+ 28 - 0
src/lib/util/tests/memory_segment_local_unittest.cc

@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include "util/memory_segment_local.h"
+#include <exceptions/exceptions.h>
 #include <gtest/gtest.h>
 #include <memory>
 
@@ -58,4 +59,31 @@ TEST(MemorySegmentLocal, TestTooMuchMemory) {
     EXPECT_THROW(segment->allocate(0x7fffffffffffffff), bad_alloc);
 }
 
+TEST(MemorySegmentLocal, TestBadDeallocate) {
+    auto_ptr<MemorySegment> segment(new MemorySegmentLocal());
+
+    // By default, nothing is allocated.
+    EXPECT_TRUE(segment->allMemoryDeallocated());
+
+    void* ptr = segment->allocate(1024);
+
+    // Now, we have an allocation:
+    EXPECT_FALSE(segment->allMemoryDeallocated());
+
+    // This should not throw
+    EXPECT_NO_THROW(segment->deallocate(ptr, 1024));
+
+    // Now, we have an deallocated everything:
+    EXPECT_TRUE(segment->allMemoryDeallocated());
+
+    ptr = segment->allocate(1024);
+
+    // Now, we have another allocation:
+    EXPECT_FALSE(segment->allMemoryDeallocated());
+
+    // This should throw as the size passed to deallocate() is larger
+    // than what was allocated.
+    EXPECT_THROW(segment->deallocate(ptr, 2048), isc::OutOfRange);
+}
+
 } // anonymous namespace