0

As I known, map value is initialized by NULL(0). However, Below code is works well without any allocation. How is this code work?

#include<bits/stdc++.h>
using namespace std;
struct stuc{
    map<string, stuc> mp;
    int cnt;
}root;

int main() {
    stuc* u = &root;
    stuc* v = &(u->mp["test"]); // how to allocate?
    cout << v->cnt << endl;
    return 0;
}
DK2
  • 651
  • 1
  • 7
  • 34

2 Answers2

3

If you access a map with the [] operator like in

&(u->mp["test"])

there is a new key value pair allocated, default initialized, and inserted into the map if the element does not already exists [1]. In your program that is exactly what happens. The map does not already have an key "test". Thus a new value is default constructed. Because you did not define a custom default constructor for your stuc struct, all its members are default initialized (mp = {} and cnt = 0). This is the reason why you get 0 if you read the cnt member of the newly created value.

[1] https://en.cppreference.com/w/cpp/container/map/operator_at

Jakob Stark
  • 3,346
  • 6
  • 22
1

When accessing a key from your std::map which does not yet exist, it is inserted.

So by accessing mp["test"] a default constructed instance of struct stuc gets inserted for key "test"

Consider the following example where also a value is implicitly inserted when accessing a non-existing key and its value being set by your default constructor

 struct stuc{
    stuc(): cnt(42) { }
    stuc(int c): cnt(c) { }
    int cnt;
};

int main() {
    map<string, struct stuc> m;

    struct stuc s1(1);

    m["first"] = s1;
    cout << m["first"].cnt << endl;
    cout << "elements: " << m.size() << endl;
    cout << m["second"].cnt << endl;
    cout << "elements: " << m.size() << endl;
    return 0;
}

which will output:

1
elements: 1
42
elements: 2
Odysseus
  • 1,213
  • 4
  • 12