0

In a running program, how can I track/print the amount of heap memory an object has allocated?

For example:

#include <iostream>
#include <vector>

int main(){

  std::vector<int> v;

  std::cout << heap_sizeof(v) << '\n';

  for (int i = 0; i < 1000; ++i){
    v.push_back(0);
  }

  std::cout << heap_sizeof(v) << '\n';
}

Is there an implementation that could substitute heap_sizeof()?

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271

3 Answers3

1

First, v is allocated on the stack, not on the heap.

To get the total amount of space used by it, I suggest using this function: (Found on this article, and modified a bit)

template <typename T>
size_t areaof (const vector<T>& x)
{
   return sizeof (vector<T>) + x.capacity () * sizeof (T);
} 

If you want not to count the size of the std::vector object itself, the delete the part with sizeof:

template <typename T>
size_t heap_sizeof (const vector<T>& x)
{
   return x.capacity () * sizeof (T);
} 
Mattia F.
  • 1,720
  • 11
  • 21
1

With everything as it's designed out of the box, no, that's not possible. You do have a couple of options for doing that on your own though.

If you need this exclusively for standard containers, you can implement an allocator that tracks the memory that's been allocated (and not freed) via that allocator.

If you want this capability for everything allocated via new (whether a container or not) you can provide your own implementation of operator new on a global and/or class-specific basis, and have it (for example) build an unordered map from pointers to block sizes to tell you the size of any block it's allocated (and with that, you'll have to provide a function to retrieve that size). Depending on the platform, this might also be implemented using platform-specific functions. For example, when you're building for Microsoft's compiler (well, library, really) your implementation of operator new wouldn't have to do anything special at all, and the function to retrieve a block's size would look something like this:

size_t block_size(void const *block) { 
    return _msize(block);
}

Yet another possibility would be to increase the allocation size of each requested block by the size of an integer large enough to hold the size. In this case, you'd allocate a bigger chunk of data than the user requested, and store the size of that block at the beginning of the block that was returned. When the user requests the size of a block, you take the correct (negative) offset from the pointer they pass, and return the value you stored there.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

If you are not concerned with accounting for what each object allocates and are more concerned with how much memory has been allocated/freed between to point in time, you can use the malloc statistics functions. Each malloc has its own version. On linux you can usemallocinfo().

doron
  • 27,972
  • 12
  • 65
  • 103