use modern construct 'nullptr' instead of 'NULL' or '0'
[platform/core/uifw/dali-core.git] / dali / internal / common / fixed-size-memory-pool.cpp
index 63e3f4b..29723b1 100644 (file)
@@ -42,14 +42,19 @@ struct FixedSizeMemoryPool::Impl
   {
     void* blockMemory;      ///< The allocated memory from which allocations can be made
     Block* nextBlock;       ///< The next block in the linked list
-
+#ifdef DEBUG_ENABLED
+    SizeType mBlockSize; ///< Size of the block in bytes
+#endif
     /**
      * @brief Construct a new block with given size
      *
      * @param size The size of the memory block to allocate in bytes. Must be non-zero.
      */
     Block( SizeType size )
-    : nextBlock( NULL )
+    : nextBlock( nullptr )
+#ifdef DEBUG_ENABLED
+      ,mBlockSize( size )
+#endif
     {
       blockMemory = ::operator new( size );
       DALI_ASSERT_ALWAYS( blockMemory && "Out of memory" );
@@ -82,7 +87,7 @@ struct FixedSizeMemoryPool::Impl
      mCurrentBlock( &mMemoryBlocks ),
      mCurrentBlockCapacity( initialCapacity ),
      mCurrentBlockSize( 0 ),
-     mDeletedObjects( NULL )
+     mDeletedObjects( nullptr )
   {
     // We need enough room to store the deleted list in the data
     DALI_ASSERT_DEBUG( mFixedSize >= sizeof( void* ) );
@@ -124,6 +129,31 @@ struct FixedSizeMemoryPool::Impl
 
     mCurrentBlockSize = 0;
   }
+#ifdef DEBUG_ENABLED
+
+  /**
+   * @brief check the memory being free'd exists inside the memory pool
+   * @param[in] memory address of object to remove
+   */
+  void CheckMemoryIsInsidePool( const void* const memory )
+  {
+    bool inRange = false;
+    const Block* block = &mMemoryBlocks;
+
+    while( block )
+    {
+      const void* const endOfBlock = reinterpret_cast<char *>( block->blockMemory )+ block->mBlockSize;
+
+      if( ( memory >= block->blockMemory ) && ( memory < (endOfBlock) ) )
+      {
+        inRange = true;
+        break;
+      }
+      block = block->nextBlock;
+    }
+    DALI_ASSERT_DEBUG( inRange && "Freeing memory that does not exist in memory pool" );
+  }
+#endif
 
   Mutex mMutex;                       ///< Mutex for thread-safe allocation and deallocation
 
@@ -166,7 +196,7 @@ void* FixedSizeMemoryPool::Allocate()
   }
 
   // Placement new the object in block memory
-  unsigned char* objectAddress = static_cast< unsigned char* >( mImpl->mCurrentBlock->blockMemory );
+  uint8_t* objectAddress = static_cast< uint8_t* >( mImpl->mCurrentBlock->blockMemory );
   objectAddress += mImpl->mCurrentBlockSize * mImpl->mFixedSize;
   mImpl->mCurrentBlockSize++;
 
@@ -175,6 +205,10 @@ void* FixedSizeMemoryPool::Allocate()
 
 void FixedSizeMemoryPool::Free( void* memory )
 {
+#ifdef DEBUG_ENABLED
+  mImpl->CheckMemoryIsInsidePool( memory );
+#endif
+
   // Add memory to head of deleted objects list. Store next address in the same memory space as the old object.
   *( reinterpret_cast< void** >( memory ) ) = mImpl->mDeletedObjects;
   mImpl->mDeletedObjects = memory;