2017-07-15 23 views
0

我有一个boost bimap如何找到内存利用由升压bimap的

#include <iostream> 
#include <utility> 
#include <boost/bimap.hpp> 
#include <boost/bimap/set_of.hpp> 
#include <boost/bimap/multiset_of.hpp> 

namespace bimaps = boost::bimaps; 
typedef boost::bimap<bimaps::set_of<unsigned long long int>, 
     bimaps::multiset_of<unsigned long long int > > bimap_reference; 
typedef bimap_reference::value_type position; 
bimap_reference numbers; 

int main() 
{ 
    numbers.insert(position(12345689, 1000000000)); 
    numbers.insert(position(23456789, 8000000000)); 
    return 0; 
} 

我有大约1.8项。理论上应该占用〜2.7GB的空间(180000000 * 8 * 2 = 2880000000字节= 2880000000/1024 * 1024 * 1024 =〜2.7GB)。现在我想找到boost bimap所用的实际空间,我该怎么做。

+0

您可能超载全球'new'和'delete'运营商,并转发给'malloc',但加入了计数器跟踪分配的字节。在填充“bimap”之前重置计数,填充它并打印字节数。 –

+0

@MatteoItalia,谢谢,一个例子会非常有帮助。 – AwaitedOne

回答

1

就像您提到的问题中的意见一样,您可以重载newdelete运算符来跟踪内存分配和释放。根据this文章全局替换节中的例子显示了一个非常简单的例子:

void* operator new(std::size_t sz) { 
    std::printf("global op new called, size = %zu\n", sz); 
    return std::malloc(sz); 
} 
void operator delete(void* ptr) noexcept { 
    std::puts("global op delete called"); 
    std::free(ptr); 
} 

这个例子,你不能确定有多少内存被释放,唯一的问题。要解决此问题,请查看How to track memory allocations in C++ (especially new/delete)accepted answer问题。

上述答案中的示例使用std::map自定义分配器来存储分配的内存块的地址和大小。在delete运算符超载内部,它将删除指定地址的元素。几乎没有修改就可以用您的要求:

#include <map> 

template<typename T> 
struct MemoryMapAllocator : std::allocator<T> { 
    typedef typename std::allocator<T>::pointer pointer; 
    typedef typename std::allocator<T>::size_type size_type; 
    template<typename U> struct rebind { typedef MemoryMapAllocator<U> other; }; 

    MemoryMapAllocator() {} 

    template<typename U> 
    MemoryMapAllocator(const MemoryMapAllocator<U>& u) : std::allocator<T>(u) {} 

    pointer allocate(size_type size, std::allocator<void>::const_pointer = 0) { 
     void* p = std::malloc(size * sizeof(T)); 
     if(p == 0) 
      throw std::bad_alloc(); 
     return static_cast<pointer>(p); 
    } 
    void deallocate(pointer p, size_type) { 
     std::free(p); 
    } 
}; 

typedef std::map<void*, std::size_t, std::less<void*>, 
      MemoryMapAllocator<std::pair<void* const, std::size_t>>> MemoryMap; 

MemoryMap& getMemoryMap() { 
    static MemoryMap memMap; 
    return memMap; 
} 

std::size_t totalAllocatedMemory() { 
    std::size_t sum = 0; 
    for(auto& e : getMemoryMap()) 
     sum += e.second; 
    return sum; 
} 

void* operator new(std::size_t size) { 
    void* mem = std::malloc(size == 0 ? 1 : size); 

    if(mem == 0) 
     throw std::bad_alloc(); 

    getMemoryMap()[mem] = size; 
    return mem; 
} 

void operator delete(void* mem) { 
    getMemoryMap().erase(mem); 
    std::free(mem); 
} 

Live Demo