2017-03-02 55 views
1

電子藝界EASTL圖書館的east::allocator要求用戶實施特殊的new操作符(如此sample所示)。這個new運營商有一個const char* name,這應該是用來記錄有關內存分配應用程序特定信息執行EASTL容器。該EASTL Best Practices指南還提到,一個人應該「名稱集裝箱跟蹤內存使用情況。如何使用EASTL跟蹤內存使用情況?

然而,似乎沒有要通過eastl::allocator::deallocate傳遞任何相應const char* name,所以不會出現是一個內置登錄內存的方式取消分配

打算如何使用EASTL調試功能?我想我一定會錯過一些東西。 EA軟件工程師在2015年也提供了一個相關的presentation,在那裏他展示了EA開發的一些用於內存調試的內部工具,似乎表明他們跟蹤分配和釋放(例如,以確保「遊戲級別1「在」遊戲等級2「開始時被釋放)。

+0

例如,分配器可以分配一個大於請求的塊,在開始處存儲名稱(和/或任何附加信息),並返回指向塊剩餘部分的指針。然後解除分配器會找到這個信息的偏移量與它給出的指針的負偏移量。 –

回答

0

EASTL的分配器是有狀態的並綁定到容器的實例;這意味着他們在實例級別定義:

什麼EASTL所做的是用更熟悉的內存分配模式 其中只有一個allocator類接口,它是由 使用的所有容器。此外EASTL容器允許你訪問他們 分配器和查詢它們,爲它們命名,改變他們,等

EASTL卻偏偏讓分配器不能集裝箱交換期間容器 之間複製和分配操作。這意味着如果 容器A與容器B交換其內容,則兩個容器 都保留其原始分配器。同樣,將容器A分配給 容器B會導致容器B保留其原始分配器。 相當的容器應該通過運算符==報告;如果分配器相等,EASTL 將執行智能交換,否則將進行蠻力交換 。

https://github.com/questor/eastl/blob/master/doc/EASTL%20Design.html

所以我會成員添加到allocator類和跟蹤內存計數裏面,像以下:

#ifndef EASTL_CUSTOM_ALLOCATOR_H_ 
#define EASTL_CUSTOM_ALLOCATOR_H_ 

#include "new_implementation.hpp" 
#include <EASTL/list.h> 
#include <iostream> 

#define DEBUG_MACRO 

class EASTL_CustomAllocator { 
public: 
    EASTL_CustomAllocator(const char* pName = EASTL_NAME_VAL(EASTL_ALLOCATOR_DEFAULT_NAME)) 
     : m_pName(pName), m_totalAmountOfBytesAllocated(0) { 
#ifdef DEBUG_MACRO 
     std::cout << m_pName << ": default construct allocator" << std::endl; 
#endif 
    } 
    EASTL_CustomAllocator(const EASTL_CustomAllocator& x) 
     : m_pName(x.m_pName), 
      m_totalAmountOfBytesAllocated(x.m_totalAmountOfBytesAllocated) { 
#ifdef DEBUG_MACRO 
     std::cout << m_pName << ": copy construct allocator" << std::endl; 
#endif 
    } 
    EASTL_CustomAllocator(const EASTL_CustomAllocator& x, const char* pName) 
     : m_pName(pName), 
      m_totalAmountOfBytesAllocated(x.m_totalAmountOfBytesAllocated) { 
#ifdef DEBUG_MACRO 
     std::cout << m_pName << ": copy construct allocator" << std::endl; 
#endif 
    } 

    EASTL_CustomAllocator& operator=(const EASTL_CustomAllocator& x) { 
#ifdef DEBUG_MACRO 
     std::cout << m_pName << ": copy assignment" << std::endl; 
#endif 
     m_pName = x.m_pName; 
     m_totalAmountOfBytesAllocated = x.m_totalAmountOfBytesAllocated; 
     return *this; 
    } 

    void* allocate(size_t num_of_bytes, int flags = 0) { 
     m_totalAmountOfBytesAllocated += num_of_bytes; 
     void* p = ::new((char*)0, flags, 0, (char*)0,  0) char[num_of_bytes]; 
#ifdef DEBUG_MACRO 
     std::cout << m_pName << ": allocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl; 
#endif 
     return p; 
    } 
    void* allocate(size_t num_of_bytes, size_t alignment, size_t offset, int flags = 0) { 
     m_totalAmountOfBytesAllocated += num_of_bytes; 
     void* p = ::new(alignment, offset, (char*)0, flags, 0, (char*)0,  0) char[num_of_bytes]; 
#ifdef DEBUG_MACRO 
     std::cout << m_pName << ": allocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl; 
#endif 
     return p; 
    } 
    void deallocate(void* p, size_t num_of_bytes) { 
     m_totalAmountOfBytesAllocated -= num_of_bytes; 
#ifdef DEBUG_MACRO 
     std::cout << m_pName << ": deallocate " << num_of_bytes << " bytes" << " at: " << (void*) p << std::endl; 
#endif 
     delete[](char*)p; 
    } 

    const char* get_name() const { 
     return m_pName; 
    } 
    void  set_name(const char* pName) { 
     m_pName = pName; 
    } 
    size_t get_totalAmountOfBytesAllocated() const { 
     return m_totalAmountOfBytesAllocated; 
    } 

protected: 
    const char* m_pName; // Debug name, used to track memory. 
    size_t m_totalAmountOfBytesAllocated; // keeps track of the memory currently allocated 
}; 


bool operator==(const EASTL_CustomAllocator& a, const EASTL_CustomAllocator& b) { 
    if (&a == &b) { 
     return true; // allocator a and b are equal if they are the same 
    } 
    else { 
     return false; // otherwhise, return false, because the state m_totalAmountOfBytesAllocated needs to be increased/decreased on splice and swap 
    } 
} 
bool operator!=(const EASTL_CustomAllocator& a, const EASTL_CustomAllocator& b) { 
    return false; 
} 


#endif /* EASTL_CUSTOM_ALLOCATOR_H_ */ 

傳遞自定義分配器類型作爲模板參數一個像下面這樣的eastl容器(你也可以在構造時用一個用戶定義的名字來設置一個實例,甚至以後可以通過set_allocator()):

eastl::list<int, EASTL_CustomAllocator> 
list(EASTL_CustomAllocator("EASTL Some Name")); 

但我不確定打算如何使用調試功能。

相關問題