How to release the vector element of STL container quickly

Posted by sglane on Thu, 24 Oct 2019 12:49:06 +0200

Because the project needs to erase the contents of the vector at some time nodes, I learned that the vector of STL has a clear function, which can be used directly. As a result, the code will have the error of the iterator crossing the boundary. Therefore, I have made a double exploration of this part. Of course, I will turn over the blogs of various gods and get some conclusions. I will attach the verification process below the conclusion:

1. The clear function is to traverse from begin to end through the iterator. If the object stored by the vector is an object, the destructor of the object will be called. Note that if the pointer is stored, the destructor of the object corresponding to the pointer will not be called, and then the elements in the container will be cleared, but the actual contents occupied by the container will not be explained. Let go;

//vector for class
class ptrclass{
public:
    ptrclass(){
        cout << "Access the ptrclass()" << endl;
    }
    ~ptrclass(){
        cout << "Access the ~ptrclass()" << endl;
    }
};
int main(int argc, char** argv){
    vector<ptrclass> ptcla;
    ptrclass* pcl1 = new ptrclass();
    ptrclass* pcl2 = new ptrclass();
    ptrclass* pcl3 = new ptrclass();
    ptcla.push_back(*pcl1);
    ptcla.push_back(*pcl2);
    ptcla.push_back(*pcl3);
    ptcla.clear();
    /*vector<ptrclass>::iterator itcls = ptcla.begin()    
    while(itcls != ptcla.end()){
        ptcla.erase(itcls);
    }*/
}

The operation result is as follows, indicating that the destructor of the object is called:

Modify the code to verify that clear cannot release the memory occupied by the container

int main(int argc, char** argv){    
    vector<string> vstr;
    string s1 = "woshia1";
    string s2 = "woshia2";
    vstr.push_back(s1);
    vstr.push_back(s2);
    cout << "ele1-addr:" << &vstr[0] << endl;
    cout << "ele2-addr:" << &vstr[1] << endl;
    cout<<vstr.empty()<<endl;
    cout<<vstr.size()<<endl;
    cout<<vstr.capacity()<<endl;
    cout<< "Before clear, the Gap of begin to end:" << vstr.end() - vstr.begin() << endl;
    vstr.clear();
    cout<< "the Gap of begin to end:" << vstr.end() - vstr.begin() << endl;
	cout << "vstr[0]:" << vstr[0].c_str() << endl;
    cout<<vstr.empty()<<endl;
    cout<<vstr.size()<<endl;
    cout<<vstr.capacity()<<endl;
    getchar();
    return 0;
}

Using g++4.8 to compile code can output results normally.

But run on vs2010 and get assertions

However, because the capacity of the vector is still kept at 2, the conclusion that the clear function fails to release memory is still true. VS just does the optimization work. It checks the usage of STL strictly. It is forbidden to access the elements in the vector that has executed clear in array mode.

2. The expression of erase function for a single element is consistent with that of clear function.

3. The swap function is used to perform the exchange. The header file needs to contain < algorithm > when it is used. When memory needs to be freed, the following operations can be performed:

int main(int argc, char**argv){
    vector<string> vstr;  //Containers to release
    string s1 = "woshia1";
    string s2 = "woshia2";
    vstr.push_back(s1);
    vstr.push_back(s2);
    cout <<&vstr[0] <<endl;
    cout <<&vstr[1] <<endl;    

    cout<<vstr.empty()<<endl;
    cout<<vstr.size()<<endl;
    cout<<vstr.capacity()<<endl;
    
    vector<string> vstr2;
    swap(vstr, vstr2);
    //Vector < int > (). Swap (obj); / / a more elegant way to write
    cout<<vstr.empty()<<endl;
    cout<<vstr.size()<<endl;
    cout<<vstr.capacity()<<endl;
    cout<<vstr2.empty()<<endl;
    cout<<vstr2.size()<<endl;
    cout<<vstr2.capacity()<<endl;
    cout <<&vstr2[0] <<endl;
    cout <<&vstr2[1] <<endl;
    return 0;
}

    

The results are as follows:

Note that the other target container of swap points to the newly initialized container vstr2, and the two are exchanged. The element pointer of container vstr2 is the same as the previous vstr element pointer, and the conclusion is valid.

Therefore, in the function body, you can quickly release the memory occupied by the original container by creating local variables and executing the swap function. However, I made the error that the iterator crossed the boundary because I accessed the elements that have been clear ed.