store string pointers in map

Hi people,
here is the code i compile under windows with code blocks and mingw gcc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <vector>
#include <map>
#include <sstream>

using namespace std;

vector<string> group_vector;
map<char, string *> keys_group_map;

void add_key_to_group(char key, string *group_name_p){
    keys_group_map[key] = group_name_p;
}

string *add_group(string group_name){
    group_vector.push_back(group_name);

    return &(group_vector.back());
}

int main(){
    add_group("Gruppo 1");
    add_key_to_group('C',&(group_vector.back()));
    cout << (*keys_group_map['C']);

    add_group("Gruppo 2");
    add_key_to_group('D',&(group_vector.back()));
    cout << (*keys_group_map['D']);

    return 0;
}


This code returns:
Gruppo 1Gruppo 2

If i change the code writing the couts near, in this way:
1
2
3
4
5
6
7
    add_group("Gruppo 1");
    add_key_to_group('C',&(group_vector.back()));

    add_group("Gruppo 2");
    add_key_to_group('D',&(group_vector.back()));
    cout << (*keys_group_map['D']);
    cout << (*keys_group_map['C']);


Now i have some garbage from the memory! Why? I'm going mad!
When we push_back() to the vector, the vector may need to allocate fresh storage and move the contents to that storage. Pointers/references to elements and iterators would be invalidated if this happens.

Either reserve() enough space in the vector so that reallocation is not required.
Or use a different container; for instance a std::list<> (or std::deque<> if there are no insertions or erasures in the middle of the sequence).
Another thought: it looks like group_vector owns the strings and keys_group_map refers to strings within it, so maybe change keys_group_map to map char to an index in the group_vector array:
map<char, size_t> keys_group_map;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
add_key_to_group(char key, size_t index)
{
    keys_group_map[key] = index;
}


int main(){
    add_group("Gruppo 1");
    add_key_to_group('C',group_vector.size()-1));
    cout << (group_vector[keys_group_map['C']]);

    add_group("Gruppo 2");
    add_key_to_group('D',group_vector.size()-1));
    cout << (group_vector[keys_group_map['D']]);

    return 0;
}
Thank you very much!
Topic archived. No new replies allowed.