Scope issue with vector of pointers (std)

I'm sure this question has been addressed already - I just can't find it anywhere (in a form I can understand). I also know that many recommend the use of smart pointers (e.g. boost), but I'm trying to do using just the standard library for now.

I have a class object I've created and I'm creating a vector of pointers to a series of these class objects. I want to initialize the vector to length 0 (since I don't know how many objects I'll eventually be referencing) and then add to that vector through a function.

The following code accomplishes this task (i.e., I can successively add to the thingAll vector):

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
  int main()
{

    vector<Thing*> thingAll;
    int menuOption;
    bool quit = false;
    
    while(quit == false) {
        cout << "1) Add thing" << endl;
        cout << "2) Quit" << endl;
        cout << "Select from the above options: ";
        cin >> menuOption;
    
        if(menuOption==1) {
            cin.ignore();
            string thing_name;
            cout << "Provide the name of the new thing: ";
            getline(cin, thing_name);
            thingAll.push_back(new Thing(thing_name));
            for(int i=0;i<thingAll.size();i++) {
                cout << (*thingAll[i]).toString() << endl;
            }
        }

        if(menuOption==2) {
            for (int i=0;i<thingAll.size();i++) {
                delete thingAll[i];
            }
            quit = true;
        }

    return 0;
}


However, the following code does not (the thingAll vector appears to be wiped clean each time the function is called):

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
  int main()
{

    vector<Thing*> thingAll;
    int menuOption;
    bool quit = false;
    
    while(quit == false) {
        cout << "1) Add thing" << endl;
        cout << "2) Quit" << endl;
        cout << "Select from the above options: ";
        cin >> menuOption;
    
        if(menuOption==1) {
            add_thing(thingAll); 
        }

        if(menuOption==2) {
            for (int i=0;i<thingAll.size();i++) {
                delete thingAll[i];
            }
            quit = true;
        }

    return 0;
}

void add_thing(vector<Thing*> thingAll) {
            cin.ignore();
            string thing_name;
            cout << "Provide the name of the new thing: ";
            getline(cin, thing_name);
            thingAll.push_back(new Thing(thing_name));
            for(int i=0;i<thingAll.size();i++) {
                cout << (*thingAll[i]).toString() << endl;
            }
}


I have not included my class definitions and member functions, but can provide them if necessary. I don't think these are the problem. Instead, I'm pretty sure it's a memory management issue - that theres something about the scope of pointers I don't understand. Thanks so much for any help.
Last edited on
void add_thing(vector<Thing*> thingAll) {
You're passing the vector by value, so the whole vector gets copied and so any changes you make to that vector (e.g. adding/removing elements) only affect the copy inside that function.

Try passing by reference instead:
void add_thing(vector<Thing*>& thingAll) {

By the way, the standard library (since C++11) now has its own smart pointer classes:
http://en.cppreference.com/w/cpp/memory
Last edited on
I also know that many recommend the use of smart pointers (e.g. boost), but I'm trying to do using just the standard library for now.


smart pointers have been part of the standard library for over 3 years. Assuming your compiler is not outdated, you should be able to use them without boost.

And yes, you should be using them.

However, the following code does not (the thingAll vector appears to be wiped clean each time the function is called):


You are passing the vector by value. This creates a copy... so the 'thingAll' in main and the 'thingAll' in add_thing are two completely different vectors.

add_thing successfully adds the thing to its vector, but main's vector remains unchanged. When add_thing exits, its vector is destroyed (leaking memory for the Thing you just created).


You probably want to pass by reference here:

 
void add_thing(vector<Thing*>& thingAll) { // <- note the & symbol added here 



Also... it's typically easier and more clear to use x->y to dereference a pointer than it is to use (*x).y:

1
2
3
cout << (*thingAll[i]).toString() << endl;
// is the same as:
cout << thingAll[i]->toString() << endl;


EDIT:

doh! ninja'd!
Last edited on
Thanks all for the quick replies. I though that pointers were reference parameters, i.e., that the effect achieved by reference parameters (use of &) was identical to the effect of pointers. I'm clearly confused on this - but thanks again for the help.

They're similar... but your vector is not a pointer. It just contains pointers.
Topic archived. No new replies allowed.