我怎么知道STL对象需要多少内存?

lim*_*imi 15 c++ memory stl

我需要在程序中收集有关内存使用情况的统计信息.

我的代码主要使用STL编写.

有没有办法了解STL对象消耗了多少内存?

例如,

string s1 = "hello";
string s2 = "hellohellohellohellohellohellohellohellohellohellohellohellohello";
Run Code Online (Sandbox Code Playgroud)

消耗了多少内存s1s2?显然,sizeof(string)+s1.length()不太准确.

Moo*_*uck 15

如果您愿意稍微介入一下,可以创建一个自定义分配器来按容器类型或已分配的类型跟踪所有堆使用情况.这非常具有侵入性,但也非常准确,用于确定内存使用情况.这不会跟踪堆本身占用多少内存,因为这是高度依赖于操作系统的.

template<class TrackType> 
size_t* mem_used() {static size_t s = 0; return &s;}

template<class T, class TrackType, class BaseAllocator = std::allocator<T> > 
class TrackerAllocator : public BaseAllocator {
public:
    typedef typename BaseAllocator::pointer pointer;
    typedef typename BaseAllocator::size_type size_type;

    TrackerAllocator() throw() : BaseAllocator() {}
    TrackerAllocator(const TrackerAllocator& b) throw() : BaseAllocator(b) {}
    TrackerAllocator(TrackerAllocator&& b) throw() : BaseAllocator(b) {}
    template <class U> TrackerAllocator(const typename TrackerAllocator::template rebind<U>::other& b) throw() : BaseAllocator(b) {}
    ~TrackerAllocator() {}

    template<class U> struct rebind {
        typedef TrackerAllocator<U, TrackType, typename BaseAllocator::template rebind<U>::other> other;
    };

    pointer allocate(size_type n) {
        pointer r = BaseAllocator::allocate(n);
        *mem_used<TrackType>() += n;
        return r;
    }
    pointer allocate(size_type n, pointer h) {
        pointer r = BaseAllocator::allocate(n, h);
        *mem_used<TrackType>() += n;
        return r;
    }
    void deallocate(pointer p, size_type n) throw() {
        BaseAllocator::deallocate(p, n);
        *mem_used<TrackType>() -= n;
    }
};
Run Code Online (Sandbox Code Playgroud)

用法是:

typedef std::basic_string<char, 
                          std::char_traits<char>,
                          TrackerAllocator<char, std::string> > trackstring;
typedef std::vector<int, 
                    TrackerAllocator<int, std::vector<int> > > trackvector;
//                                        ^              ^
//                                        This identifies which memory to track
//                                        it can be any type, related or no.
//                                        All with the same type will be tracked togeather
int main() {
    trackstring mystring1("HELLO WORLD");
    std::cout << *mem_used<std::string>() << '\n'; //display memory usage of all strings

    trackstring mystring2("MUCH LONGER STRING THAT DEFINITELY GETS HEAP ALLOCATED!");
    std::cout << *mem_used<std::string>() << '\n'; //display memory usage of all strings

    trackvector myvec(mystring1.begin(), mystring1.end());
    std::cout << *mem_used<std::vector<int> >() << '\n'; //display memory usage of all vector<int>
    //                     ^              ^
    //                     This identifies which memory type from above to look up.
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Windows结果:

0 //这是零,因为字符串没有分配堆空间.
64
11

http://ideone.com/lr4I8(GCC )成果:

24
92
11


Naw*_*waz 5

由于这是完全实现的细节,因此无法100%准确判断.

但是,正如您所说,您希望使用一些代码来统计程序中的内存使用情况,然后您可以准确地执行此操作.

我相信,因为std::string字符串对象占用的内存大小几乎等于:

size_t statisticalSizeStr = sizeof(string)+ s.capacity() * sizeof(char);
Run Code Online (Sandbox Code Playgroud)

同样地,对于 std::vector

size_t statisticalSizeVec = sizeof(std::vector<T>)+ ....;
Run Code Online (Sandbox Code Playgroud)

您可以对此类信息建模统计估算.对于矢量,您还可以考虑T填充....上述等式的相同方式的大小.例如,如果Tstd::string,那么:

size_t vecSize = sizeof(std::vector<std::string>);
size_t statisticalSizeVec = vecSize  + v.capacity() * statisticalSizeStr;
Run Code Online (Sandbox Code Playgroud)

如果Tint,那么

size_t statisticalSizeVec=sizeof(std::vector<int>)+v.capacity()*sizeof(int);
Run Code Online (Sandbox Code Playgroud)

我希望,这样的分析可以帮助您尽可能准确地计算尺寸.