views:

221

answers:

5
class Help
{
public:
        Help();
        ~Help();

        typedef std::set<string> Terms;
        typedef std::map<string, std::pair<int,Terms> > TermMap;
        typedef std::multimap<int, string, greater<int> > TermsMap;

private:

        TermMap  terms;
        TermsMap    termsMap;
};

How can we find the memory used (in bytes) by the objects term and termsMap. Do we have any library ?

A: 

the sizeof() operator ought to do it:

size_t bytes = sizeof(Help::TermMap);
e.James
`sizeof` is an operator, not a function.
Carl Norum
@Carl Norum: right you are. Thank you for the reminder!
e.James
Hmm. This doesn't seem to work, for two reasons: the members are private, and you are not allowed to take the size of a non-static member variable. Interesting!
e.James
It can be done within any member function
hype
@e.James: make it sizeof(Help::TermMap)
Georg Fritzsche
Ah. This is what happens when I answer questions instead of sleeping. Thanks, guys. Answer is now CW.
e.James
+1  A: 

If you're looking for the actual block of memory, the numerical value of a pointer to it should be it. (Then just add the number of bytes, and you have the end of the block).

Narfanator
+4  A: 

If you are looking for the full memory usage of an object, this can't be solved in general in C++ - while we can get the size of an instance itself via sizeof(), the object can always allocate memory dynamically as needed.

If you can find out how big the individual element in a container are, you can get a lower bound:

size = sizeof(map<type>) + sum_of_element_sizes;

Keep in mind though that the containers can still allocate additional memory as an implementation detail and that for containers like vector and string you have to check for the allocated size.

Georg Fritzsche
Consider that as a rough underestimate. In many cases, like with maps, the STL must contain other things (map is a balanced tree, so it will need at least three pointers (left, right, parent - parent to guarantee fast iterator transversal) and some way of keeping info for the balance invariant, probably an extra value (integer, color byte)... and the element size has to consider both the key and the value.
David Rodríguez - dribeas
David, changed it to *lower bound* to make it clearer, the rest should be covered by *implementation details*.
Georg Fritzsche
+3  A: 

Short Answer: No

Long Answer:
-> The basic object yes. sizeof(<TYPE>) but this is only useful for limited things.
-> A container and its contained members: NO

If you make assumptions about the structures used to implement these objects you can estimate it. But even that is not really useful ( apart from the very specific case of the vector).

The designers of the STL deliberately did not define the data structures that should be used by these containers. There are several reasons for this, but one of them (in my opinion) is to stop people making assumptions about the internals and thus try and do silly things that are not encapsulated by the interface.

So the question then comes down to why do you need to know the size?
Do you really need to know the size (unlikely but possible).

Or is there a task you are trying to achieve where you think you need the size?

Martin York
+3  A: 

How can we find the memory used (in bytes) by the objects term and termsMap. Do we have any library ?

You should use your own allocator type.

typedef std::set<string, 
    your_allocator_1_that_can_count_memory_consumption_t> Terms;

typedef std::map<string, std::pair<int,Terms>,
    your_allocator_2_that_can_count_memory_consumption_t> TermMap;

typedef std::multimap<int, string, greater<int>, 
    your_allocator_3_that_can_count_memory_consumption_t> TermsMap;

I have not yet checked this idea for std::string so if it is difficult to implement just use your own class fixed_string which just wraps char s[max-string-lenght].

And when you need in your program to find out memory consumption just get it from your_allocator_1_that_can_counts_memory_consumption_t, your_allocator_2_that_can_counts_memory_consumption_t, your_allocator_3_that_can_counts_memory_consumption_t.

Edited

For UncleBens I want to clarify my point.

As far as I understand the question of the ARV it is necessary to know how much memory is allocated for set::set and std::map including all memory allocated for elements of the set and the map. So it is not just sizeof(terms).

So I just suggested a very simple allocator. Without going into too much details it might look like this:

template <class T>
class your_allocator_1_that_can_counts_memory_consumption_t {
public:
   // interfaces that are required by the standart
private:
   std::allocator<T> std_allocator_;
   // here you need to put your variable to count bytes
   size_t globale_variable_for_allocator_1_to_count_bytes_;
};

This allocator just counts number of allocated and deallocated bytes and for real allocation and deallocation use its member std_allocator_. I might need to debug it under gdb in order to set a breakpoint on malloc() and on free() to make sure that every allocation and deallocation actually goes through my allocator.

I would be grateful if you point me at some problems with this idea since I have already implemented it in my program that runs on Windows, Linux and HP-UX and I simply asks my allocators in order to find how much memory each of my containers use.

skwllsp
I suspect that unless your allocator uses some very OS-specific allocation routines, you won't be able to tell the memory usage even then. If I'm not mistaken, if your code contains something as high-level as `malloc(n);` it might still be completely implementation-defined how much memory actually got "used up".
UncleBens
See the edited part.
skwllsp
One more point about `it might still be completely implementation-defined how much memory actually got "used up"`. That is true. For example on HP-UX when you ask for 5 bytes sometimes 16 bytes are in fact allocated since libc cares about memory fragmentation. However I also get information from HP-UX/Linux as to how much memory is allocated to a process. As a result I know that real memory consumption is bigger.By the way ARV did not say that he wanted to know exact memory consumption by the containers including what might be added by a libc.
skwllsp