Freeing / Removing C ++ Vector Dynamic Memory

When I try to delete the dynamic memory elements of a dynamic vector of objects, I have to repeat the entire size of the vector several times to ensure full release.

class CV{
    public:
            float x;
            float y;

            CV();
            CV(float, float);
            ~CV();
 };


int main(){

    vector<CV*>* cars;
    cars = new vector<CV*>;


    //create objects with new, push into vetor
    for(int j=0;j<4;j++){
            cars->push_back( new CV(10.0+j, 11.99+j) );
    }

    while( cars->size() > 0   ){
            for(int i=0;i<cars->size();i++){
                    delete (*cars)[i];
                    cars->erase( cars->begin()+i);
            }
            cout << "size:"<< cars->size() << endl;
    }

    delete cars;
    return 0;

}

This will output:

  size:2
  size:1
  size:0

It seems that the vector repeats for every second element when I try to delete, since I need an extra while loop to ensure full release.

It seems that I have something missing about the internal functions of the vector, I tried reading the C ++ vector link, and I understand that the vectors store the elements in an adjacent location and that they provide additional storage for possible growth, but I can not understand the behavior of this code.

+4
4

template<typename T>
void destroy_vector(std::vector<T*> &v)
{
    while(!v.empty()) {
        delete v.back();
        v.pop_back();
    }
}

  • empty
  • vector<T*>* , .
+2

, . 0, 1 0 .

. .

+1

, - . :

auto validateLoopCondition = [](int index, const vector<CV*> *vecpCV)
{
    cout << "validate loop condition: i = " << index << ", size:" << vecpCV->size()
         << (index < vecpCV->size() ? ", keep it" : ", break out\r\n---------------\r\n")
         << endl; 
};

for (int i = 0;  validateLoopCondition(i, cars) , i < cars->size(); i++)
{
    delete (*cars)[i];
    cars->erase(cars->begin() + i);
}

cout << "size:" << cars->size() << endl;


//-out put-----------------------------------------------

validate loop condition: i = 0, size:4, keep it
validate loop condition: i = 1, size:3, keep it
validate loop condition: i = 2, size:2, break out
---------------

size:2
validate loop condition: i = 0, size:2, keep it
validate loop condition: i = 1, size:1, break out
---------------

size:1
validate loop condition: i = 0, size:1, keep it
validate loop condition: i = 1, size:0, break out
---------------

size:0

//--------------------------------------------- --------

, :

  • .

  • Using a vector object on the stack would be better.

0
source

The reason for this is very simple: you pull the carpet out from under your feet, erasing element i, and then increasing i ...

i = 0: cars = {0} [1] [2] [3]

delete (start + i)

i = 0: cars = {1} [2] [3]

i ++

i = 1: cars = [1] {2} [3]

delete (start + i)

i = 1: cars = [1] {3}

i ++

i> = cars.size ()

Using erasure like this is inefficient. You can consider the following two approaches:

while (!cars.empty()) {
    delete cars.back();
    cars.pop_back();
}

or much more effective

for (size_t i = 0; i < cars.size(); ++i) {
    delete cars[i];
}
cars.clear();
0
source

Source: https://habr.com/ru/post/1528165/


All Articles