laoqiren laoqiren - 12 days ago 5
C++ Question

vector in C++ can only read the last element

I add several element to the vector, but when I visit them, they are all the one which is added at last. I can't understand.

here is my code:

while(true){
cin>>shape;
if(shape=='X') break;
if(shape=='C'){
cin>>x>>y>>r;
Circle c(x,y,r);
shapes[sum] = &c;
//cout<<shapes[sum]->getArea()<<endl;
sum++;
}else if(shape=='R'){
cin>>x1>>y1>>x2>>y2;
Rectangle rec(x1,y1,x2,y2);
shapes[sum] = &rec;
//cout<<shapes[sum]->getArea()<<endl;
sum++;
} else if(shape=='T'){
cin>>x1>>y1>>x2>>y2>>x3>>y3;
Triangle tr(x1,y1,x2,y2,x3,y3);
shapes[sum] = &tr;
//cout<<shapes[sum]->getArea()<<endl;
sum++;
}
}
for(int j=0; j<sum; j++){
showArea(shapes[j]);
}


I found that at last, all the element in the vector is same, they are the element which is added at last.

Answer

Your vector stores pointer. And you store inside it pointer of local variables:

} else if(shape=='T'){
    cin>>x1>>y1>>x2>>y2>>x3>>y3;
    Triangle tr(x1,y1,x2,y2,x3,y3); // <= Create local variable, automatic allocation
    shapes[sum] = &tr; // <= store its address
    //cout<<shapes[sum]->getArea()<<endl;
    sum++;
} // <= automatic dealocation of tr, ie tr doesn't exist anymore
  // shapes[sum - 1] stores address of no more existing variable => Undefined behavior

you should do:

} else if(shape=='T'){
    cin>>x1>>y1>>x2>>y2>>x3>>y3;
    Triangle *tr = new Triangle(x1,y1,x2,y2,x3,y3); // manual allocation
    shapes.push_back(tr);
    //cout<<shapes[sum]->getArea()<<endl;
    sum++;
} 

BUT you have to deallocate with delete when you don't need anymore objects in vector


sum isn't necessary: you have to use push_back to avoid Undefined Behavior, and after, you can use shapes.size() to retrieve size of vector.

Indeed, accessing to an element of vector which is out of bound (ie when you do vector[n], n is equal or greater than vector.size()) is undefined behavior.


Modern way of doing this: use of shared_ptr or unique_ptr