which is better - 3 ways to add an entry to map

I have the following code in sourceFile.cpp. functionA() is first called and inserted entires for key1, key2 and key3. Then functionB() gets called to use the vectors for the 3 keys. I want to free all memory after exiting functionC(). Among the three ways to put an entry into the map for the 3 keys, which is correct / better?

Class ClassA { ... }

ClassA *key1 = new ClassA();
ClassA *key2 = new ClassA();
ClassA *key3 = new ClassA();

static map<ClassA*, vector<pair<char*, char*> > > stringMap;

// which way of adding an entry into StringMap is better? key1, key2 or key3
void functionA() {
// insert entries into stringMap for key1 and key2
vector<pair<char*, char*> > *v1 = new vector<pair<char*, char*> >();
stringMap[key1] = *v1;
stringMap[key2]; // map will insert one vector<pair<char*, char*> > object
// is this vector object on heap or stack?

vector<pair<char*, char*> > v3;
stringMap[key3] = v3; //
}

void functionB() {
// get entries for key1, key2 and key3
// use vector.push_back() to populate vectors
}

void functionC() {

// so when program exits this function, all memory is released
vector<pair<char*, char*> > *v1 = stringMap[key1];
v1->clear(); // or loop and v1->erase()
stringMap.erase(key1);
delete v1;

vector<pair<char*, char*> > v2 = stringMap[key2];
v2.clear();
stringMap.erase(key2);
// v2 was inserted by map, does it need to delete v2 ???

// what about the vector for key3?
}
I want to free all memory after exiting functionC()

The easiest way to do that is to never call new.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <map>
#include <vector>
#include <string>

struct ClassA {
    int val;
    ClassA(int v) : val(v) {}
};
bool operator<(const ClassA& lhs, const ClassA& rhs) { return lhs.val < rhs.val; }

ClassA key1(1);
ClassA key2(2);
ClassA key3(3);

std::map<ClassA, std::vector<std::pair<std::string, std::string>>> stringMap;

void functionA()
{
    // no point
}

void functionB()
{
    stringMap[key1].push_back(std::make_pair("foo", "bar"));
    stringMap[key1].push_back(std::make_pair("baz", "xyzzy"));
    stringMap[key2].push_back(std::make_pair("one", "two"));
    stringMap[key3].push_back(std::make_pair("one", "two"));
}

void functionC()
{
    stringMap.clear();
}

int main()
{
    functionB();
    for(auto& v: stringMap)
    {
        std::cout << v.first.val << " => {";
        for(auto& p: v.second)
            std::cout << " '" << p.first << "','" << p.second << "' ";
        std::cout << "}\n";
    }
    functionC();
}

online demo: http://ideone.com/bUceVV

although it's even better if you can scope the lifetime of stringMap, so that it ends where you would otherwise call functionC().
Last edited on
Thanks, Cubbi. You provided a very nice solution. I'd like to give more information for the question. ClassA is in shared library which I cannot change it at all. My current implementation uses a pointer to ClassA to pass around and invoke functionB and C. Do you think I can write a struct to wrap ClassA in shared library? Also I don't think I can pass any int value for comparison. Also, in a multi-threading environment, the map and vector may not be thread safe.
Last edited on
Topic archived. No new replies allowed.