1

I'm using std::map, and can't understand how much memory it consumes.

I have the following map definitions:

CKey {
 long x;
 int y;
 int z;
 bool operator<(const CKey& l) const;
};

CValue {
 int data1;
 int data2;
}

std::map<CKey, CValue> map;
std::cout << "sizeof() = " << sizeof(map) << " Max #Elms = " << map.max_size();

(No mater before or after inserting elements into the map) I'm getting that.

sizeof() = 48
Max_Size = 329406144173384850
  1. If sizeof(map) = 48, how can it contains 329406144173384850 elements ?
  2. Does the map save the <CKey,Cvalue> in other memory (heap ?)
Eric
  • 336
  • 4
  • 17
Boom
  • 1,145
  • 18
  • 44
  • 1
    http://en.cppreference.com/w/cpp/container/map/max_size `max_size` will give you the maximum number of element you may put in the map given your current system, not the number of pairs that are in the map. – Matteo Ragni Oct 22 '17 at 13:07
  • 2
    The `sizeof` operator returns the size of the *object*, not the data it contains. It's simply a sum of the `sizeof` of all members (plus potential padding). It's like doing `sizeof(some_pointer)`, which returns the size of the *pointer*, and not the size of the data pointed to. – Some programmer dude Oct 22 '17 at 13:08
  • 1
    MaxSize is not what you think, and Sizeof is also not what you think. RTFM for all's sake instead of guessing just by their name. – quetzalcoatl Oct 22 '17 at 13:09
  • 1
    Possible duplicate of [c++ sizeof() of a class with functions](https://stackoverflow.com/questions/6552319/c-sizeof-of-a-class-with-functions) -- it is not "exact duplicate" since it asks about a "class with functions" but it's hard to deny that a std::map is a class, and that it has methods. – quetzalcoatl Oct 22 '17 at 13:11
  • 1
    Instead of `sizeof(map)` you need `map.size()`. – rustyx Oct 22 '17 at 13:13
  • hm... however, to be fair, I have to give it a plus, since in fact this is one of the better-formulated questions asking about `sizeof`. Good job, seriously! – quetzalcoatl Oct 22 '17 at 13:14
  • Oh, one more thing, the "consumption of memory" may be hard to determine. Map is not a simple array, knowing how many elements (see RustyX's comment) won't tell you much more than just general idea of the order of magnitude. map of 4-byte int with 10^6 elements will take much more than 4mb of memory. – quetzalcoatl Oct 22 '17 at 13:17

2 Answers2

7

In C and C++, the sizeof operator tells you how many bytes of stack space an instance of the class will occupy.

Like the other standard containers (except std::array), map allocates its elements on the heap when using the default allocator. This means that its static size (i.e. what sizeof returns) does not depend on the number of elements in the map.

You can find out how many elements are in a map using the size() member function. The max_size() member function on the other hand tells you how many elements the map could theoretically store -- on a 64-bit system, you are almost certainly going to be limited by the amount of RAM on your system rather than what max_size() returns.

Actually working out the total memory use (stack and heap) of a map is not an easy thing to do: in C++17 you might be able to do something like

sizeof(map) + map.size() * sizeof(typename map::node_type);

to give you a rough guess, but really it will depend on the implementation details of your standard library.

Tristan Brindle
  • 16,281
  • 4
  • 39
  • 82
1

std::map defines the following methods

max_size()

Returns the maximum number of elements the container is able to hold due to system or library implementation limitations

size()

Returns the number of elements in the container

So, the following calculation will give you a good approximation of the actual size of the map in bytes (Given that the Key and Value types are structs of primitive types):

sizeof(mymap) + mymap.size() * (sizeof(decltype(mymap)::key_type) + sizeof(decltype(mymap)::mapped_type))
Daniel Trugman
  • 8,186
  • 20
  • 41
  • 1
    `the following calculation will give you the actual size of the map in bytes ` - I really doubt that it will. IIRC Map is often implemented as a **tree**, so you will have **at least** log(N) pointer overhead – quetzalcoatl Oct 22 '17 at 13:25
  • @quetzalcoatl, you are 100% correct. I fixed my mistake to explicitly state that this is an approximation! – Daniel Trugman Oct 22 '17 at 13:38