Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vector.push_back() crashes

Tags:

c++

vector

I have a problem while working with vectors of a class. I have tried whittling away at the code as much as possible, leaving me with the code below. Yet, after doing this, I still cannot figure out why my program is crashing. I come from a world of VBA and my C++ debugging skills are poor to say the least and I apologize for that up front. Any guidance to improve my ability here will be gladly accepted.

My class:

class Tester {
public:

    int varA;
    int varB;

    Tester() {
        varA = 1;
        varB = 1;
    }

    Tester(Tester& P1, Tester& P2) {
        varA = P1.varA + P2.varA;
        varB = P1.varB + P2.varB;
    }

    Tester(const Tester &Source) {
        varA = Source.varA;
        varB = Source.varB;
    }

};

My test mains:
Does not work:

int main() {
std::vector < Tester > BreakIt;

    for (int i = 0; i < 2500; i++) {
        Tester newTester;
        BreakIt.push_back(newTester);
        Tester& tempTester = BreakIt.at(0);
        for (int j = 0; j < 4; j++) {
            BreakIt.push_back(Tester(newTester, tempTester)); //This is where it crashes.
        }
    }

return 0;
}

Does work:

int main() {
std::vector < Tester > BreakIt;

    Tester newTester;
    BreakIt.push_back(newTester);

    for (int i = 0; i < 2500; i++) {
        Tester& tempTester = BreakIt.at(0);
        for (int j = 0; j < 4; j++) {
            BreakIt.push_back(Tester(newTester, tempTester));
        }
    }

return 0;
}

Does work:

int main() {
std::vector < Tester > BreakIt;

    for (int i = 0; i < 2500; i++) {
        Tester newTester;
        BreakIt.push_back(newTester);
        Tester& tempTester = BreakIt.at(0);
    }

return 0;
}

The push_back() line that breaks does run a few times before the crash. It seems that when I change certain things around and recompile, the point at which it crashes changes (i.e. 20 times through the main loop vs. 175 times vs. 1000 times). However, once I've compiled, it will typically run through the the same iteration each time before crashing.

I suspect that this is some kind of 'undefined behavior' but from where I'm not sure.

Can someone please help me identify why BreakIt.push_back(Tester(newTester, tempTester)); does not work where I want it to?

like image 655
Gaffi Avatar asked Mar 21 '12 12:03

Gaffi


1 Answers

You're right, there is undefined behaviour.

You're taking a reference to BreakIt.at(0); however this object is no longer guaranteed to exist after you've done a push_back, because if the vector grows, all of the contents are typically copied, and the originals deleted.

From http://www.cplusplus.com/reference/stl/vector/push_back/ (not the world's best reference):

Reallocations invalidate all previously obtained iterators, references and pointers.

like image 188
Oliver Charlesworth Avatar answered Oct 07 '22 16:10

Oliver Charlesworth