0

I have two classes which is a direct inheritance with no override, so they are basically: vector<string> list and vector< reference_wrapper<string> > filtered. The idea is I want to store all values into list and then fill the filtered with selected data from list.

Now, when I do filtered.push_back() if it has size of 1, the reference at index 0 would return an empty string (length = 0).

// concept code
int main() {
    vector<string> list;
    vector< reference_wrapper<string> > filtered;

    string line;
    for (;;) {
        if (!getline(cin, line, '\n').good()) {
            cout << "Bad input! Exiting..." << endl;
            break;
        } else if (line.length() > 0) {
            break;
        } else {
            list.push_back(line);
            //   filtered[0].length() NOT 0 (size() = 1)
            filtered.push_back(list.back());
            //   filtered[0].length() is now 0
        }

        // then print to screen... cout
    }

Why does this happen?


Here's an example:

// cout when size() = 1
[1] Hello world

// cout when size() = 2
[1] 
[2] Hi!

// cout when size() = 3
[1] 
[2] Hi!
[3] My world
T.N.
  • 33
  • 8

1 Answers1

4

push_back to vector invalidates all previous references/pointers/iterators if a grow operation is triggered and trying to use them after growing is undefined behavior.

In your case the 2nd list.push_back(line); is actually triggering a grow, making the previous reference_wrapper in filtered invalid. While you are trying to access them, you are invoking undefined behavior.

If you want to use in this way you have to ensure that the vector has enough space so that a grow operation is not triggered.

Tas
  • 7,023
  • 3
  • 36
  • 51
taskinoor
  • 45,586
  • 12
  • 116
  • 142
  • Ohh... so it's better to store the `index` from the `list` instead of the reference then? – T.N. Mar 27 '18 at 05:36
  • @T.N. index doesn't get invalidated. But not sure whether it will be better without getting more context on what you are actually trying to do. – taskinoor Mar 27 '18 at 05:38
  • Well, I just trying to have a source vector and filtered vector so if I modify something in the filtered vector it will also reflect to the source. Maybe I will use `vector` instead. Thanks! – T.N. Mar 27 '18 at 05:41