How to track memory usage using EASTL?

心已入冬 提交于 2019-12-02 04:50:46

The allocators by the EASTL are stateful and bound to the instance of the container; meaning they are defined at instance level:

What EASTL does is use a more familiar memory allocation pattern whereby there is only one allocator class interface and it is used by all containers. Additionally EASTL containers let you access their allocators and query them, name them, change them, etc.

EASTL has chosen to make allocators not be copied between containers during container swap and assign operations. This means that if container A swaps its contents with container B, both containers retain their original allocators. Similarly, assigning container A to container B causes container B to retain its original allocator. Containers that are equivalent should report so via operator==; EASTL will do a smart swap if allocators are equal, and a brute-force swap otherwise.

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

So I would add a member to the allocator class and track the memory count inside it, like following:

#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_ */

Pass that custom allocator type as a template parameter to a eastl container like following (also you can set a instance with a user-defined name at construction and even later by set_allocator()):

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

But I'm not sure how the debugging functionality is intended to be used.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!