0

I wrote a simple program below for the explain.

class A{
public:
    int *x;

    A(){ x = 0; }
    ~A(){ delete x; }

    void foo(){
        x = new int();
        *x = 99;
    }
};

int main(){
    std::vector<A> as;
    for (int i = 0; i < 3; ++i){
        as.push_back(A());
        as.back().foo();
    }
    return 0;
}

I expect that as contains 3 instance of A.
But the pointer x of the first element lose its reference(written dummy value) after second push_back is called, and an exception is thrown at 3rd iteration.

This is resolved adding as.reserve(3) before for loop.

Why this happened?

Shayan Ghosh
  • 882
  • 6
  • 14
Hyunan Kwon
  • 545
  • 1
  • 4
  • 14
  • You are violating the Rule of Three (or rather the Rule of Zero), and so your vector blows up when it reallocates. – Kerrek SB Dec 02 '15 at 10:09
  • Thank you for the fast reply, I'll check it. – Hyunan Kwon Dec 02 '15 at 10:12
  • @KerrekSB I already know that notion(but not the term "the Rule of Three"). I think that **A()** and **as.back()** are different instances, so it's not matter because the heap allocation occurs after copy construction. I mean, **as.back()** is the element of **as**. Am I wrong? – Hyunan Kwon Dec 02 '15 at 10:31
  • 1
    The problem occurs in `as.push_back(A())`, which *reallocates* the internal memory, thereby *copying* the internal elements and running your broken destructor. In other words, `vector` requires `T` to be copyable, but your type is not copyable since copying breaks the class invariants. (The class invariants in turn are described by the class destructor.) – Kerrek SB Dec 02 '15 at 10:56
  • Yeah, @HyunanKwon, you're almost right, but you forgot that `push_back` results in element copies too. – Lightness Races in Orbit Dec 02 '15 at 11:14
  • Oh, now I get it. Thanks all. – Hyunan Kwon Dec 03 '15 at 03:58

0 Answers0