zoukankan      html  css  js  c++  java
  • C++——STL内存清除

    1.vector元素的清除

    看代码。在vector中添加若干元素,然后clear()

     1 #include<iostream>
     2 #include<list>
     3 #include<vector>
     4 #include<iterator>
     5 #include<string>
     6 using std::vector;
     7 using std::list;
     8 using std::iterator;
     9 using std::string;
    10 using std::cout;
    11 using std::endl;
    12 
    13 int main()
    14 {
    15     vector<string> vecStr;
    16     string pStr1 = "Robb";
    17     vecStr.push_back(pStr1);
    18     string pStr2 = "Bran";
    19     vecStr.push_back(pStr2);
    20     string pStr3 = "Snow";
    21     vecStr.push_back(pStr3);
    22     string pStr4 = "Sansa";
    23     vecStr.push_back(pStr4);
    24     string pStr5 = "Arya";
    25     vecStr.push_back(pStr5);
    26     
    27     /*打印*/
    28     for(auto unit:vecStr)
    29     {
    30         cout<<"-----"<<unit<<"-----"<<endl;
    31     }
    32     /*释放前vector的容量*/
    33     cout<<"释放前vector的容量"<<endl;
    34 
    35     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    36     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    37 
    38     /*释放*/
    39     vecStr.clear();
    40     cout<<endl<<"clear后vector的容量"<<endl;
    41 
    42     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    43     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    46     system("pause");
    47     return 0;
    48 }

    输出结果如图:

    size是变小了,但是capacity并没有变小。

    我们加一下代码

    1     /*swap*/
    2     vector<string>().swap(vecStr);
    3     cout<<endl<<"swap后vector的容量"<<endl;
    4 
    5     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    6     cout<<"vecStr.capacity():"<<vecStr.capacity()<<end

    使用swap之后,就清空了capacity。

    这是为什么呢?

    vector由于是一个不定长存储的数据结构,每一次分配的大小都是比面前输入的数据个数略大一点(实际上也并不准确,参看2)code中注释,是介于2^n与2^(n+1)之间),所以每一次push_back()且发现当被分配的存储空间已装满数据时,都是将包含现有数据的vector进行拷贝,进入一个更大一点的vector,而原有的vector就会被自然销毁,我们用.swap()释放内存的原理其实是相似的,即手动进行了一次人工拷贝的操作。(https://blog.csdn.net/a272846945/article/details/51182144 )

    由于vector的空间是阶梯递增式管理的,而且基本只增不减,也就是说,虽然调用remove、erase或者clear等方法(他们会调用所存元素对象的析构函数),确实会释放掉一些内存,但是,容器之前分配的空间仍不会被回收,大小不变,仍旧不能被其他程序使用,这是由STL的内存管理机制决定的,目的是为了提高效率。 (https://www.cnblogs.com/EE-NovRain/archive/2012/06/12/2546500.html)

     下面有一个调用函数的例子,感觉还是有很多东西

    ①内存增长方式,指数增长。2^n。数量增大到capacity的时候,整体拷贝,然后析构之前的内存。

    ②push_back,调用复制构造函数。

     1 class CUnit
     2 {
     3 private:
     4     /* data */
     5     string m_name;
     6 public:
     7 
     8     CUnit(string name)
     9     {
    10         m_name = name;
    11         //cout<<this<<",create"<<endl;
    12     }
    13     ~CUnit()
    14     {
    15         //delete member
    16         cout<<this<<",destroy"<<endl;
    17     }
    18     CUnit(const CUnit & c)
    19     {
    20         //cout<<&c<<",param"<<endl;
    21         //cout<<this<<",copy"<<endl;
    22     } 
    23     string& getName(){return m_name;}
    24 };
    25 
    26 
    27 int main()
    28 {
    29     vector<CUnit> vecStr;
    30     CUnit cUnit1 = CUnit("Robb");
    31     vecStr.push_back(cUnit1);    //此处调用复制构造函数
    32     
    33     cout<<"push one"<<endl;
    34 
    35     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    36     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    37 
    38 
    39     CUnit cUnit2 = CUnit("Bran");//size不够,多次复制构造
    40     vecStr.push_back(cUnit2);
    41         
    42     cout<<"push two"<<endl;
    43 
    44     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    45     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    46     CUnit cUnit3 = CUnit("Snow");//size不够,多次复制构造
    47     vecStr.push_back(cUnit3);    
    48     CUnit cUnit4 = CUnit("Arya");//size不够,多次复制构造
    49     vecStr.push_back(cUnit4);
    50     CUnit cUnit5 = CUnit("Sansa");//size不够,多次复制构造
    51     vecStr.push_back(cUnit5);
    52     cout<<"push five"<<endl;
    53     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    54     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    55     cout<<endl;
    56     
    57     /*打印*/
    58     for(auto unit:vecStr)
    59     {
    60         cout<<"-----"<<unit.getName()<<"-----"<<endl;
    61     }
    62     /*释放前vector的容量*/
    63     cout<<"释放前vector的容量"<<endl;
    64 
    65     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    66     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    67 
    68     /*释放*/
    69     vecStr.clear();
    70     cout<<endl<<"clear后vector的容量"<<endl;
    71 
    72     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    73     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    74 
    75     /*swap*/
    76     vector<CUnit>().swap(vecStr);
    77     cout<<endl<<"swap后vector的容量"<<endl;
    78 
    79     cout<<"vecStr.size()    :"<<vecStr.size()<<endl;
    80     cout<<"vecStr.capacity():"<<vecStr.capacity()<<endl;
    81 
    82     system("pause");
    83     return 0;
    84 }

    2.list的清内存

     1 class CUnit
     2 {
     3 private:
     4     /* data */
     5     string m_name;
     6 public:
     7 
     8     CUnit(string name)
     9     {
    10         m_name = name;
    11         //cout<<this<<",create"<<endl;
    12     }
    13     ~CUnit()
    14     {
    15         //delete member
    16         cout<<this<<",destroy"<<endl;
    17     }
    18     CUnit(const CUnit & c)
    19     {
    20         //cout<<&c<<",param"<<endl;
    21         //cout<<this<<",copy"<<endl;
    22     } 
    23     string getName(){cout<<this<<",copy"<<endl;return m_name;}
    24 };
    25 
    26 
    27 int main()
    28 {
    29     list<CUnit*> listStr;
    30     CUnit *cUnit1 = new CUnit("Robb");
    31     listStr.push_back(cUnit1);    //此处调用复制构造函数
    32     
    33     cout<<"push one"<<endl;
    34     cout<<"listStr.size()    :"<<listStr.size()<<endl;
    35 
    36     CUnit* cUnit2 = new CUnit("Bran");//size不够,多次复制构造
    37     listStr.push_back(cUnit2);
    38         
    39     cout<<"push two"<<endl;
    40     cout<<"listStr.size()    :"<<listStr.size()<<endl;
    41     CUnit *cUnit3 = new CUnit("Snow");//size不够,多次复制构造
    42     listStr.push_back(cUnit3);    
    43     CUnit *cUnit4 = new CUnit("Arya");//size不够,多次复制构造
    44     listStr.push_back(cUnit4);
    45     CUnit *cUnit5 = new CUnit("Sansa");//size不够,多次复制构造
    46     listStr.push_back(cUnit5);
    47 
    48     cout<<"push five"<<endl;
    49     cout<<"listStr.size()    :"<<listStr.size()<<endl;
    50     cout<<endl;
    51     
    52     /*打印*/
    53     for(list<CUnit*>::iterator it = listStr.begin(); it!=listStr.end();it++)
    54     {
    55         cout<<"-----"<<(*it)->getName()<<"-----"<<endl;
    56     }
    57     /*释放前list的容量*/
    58     cout<<"释放前list的容量"<<endl;
    59     cout<<"listStr.size()    :"<<listStr.size()<<endl;
    60     cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
    61 #if 1              //调用析构函数,清掉了list的内存
    62     for(list<CUnit*>::iterator it = listStr.begin(); it!=listStr.end();)
    63     {
    64          delete *it;
    65         listStr.erase(it++);
    66         //cout<<"-----"<<(*it)->getName()<<"-----"<<endl;
    67     }
    68 
    69     cout<<"释放后list的容量"<<endl;
    70     cout<<"listStr.size()    :"<<listStr.size()<<endl;
    71     cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
    72 #endif
    73 
    74 #if 0              //并不会调用析构函数,只是清掉了list的内存
    75     /*释放*/
    76     listStr.clear();
    77     cout<<endl<<"clear后list的容量"<<endl;
    78     cout<<"listStr.size()    :"<<listStr.size()<<endl;
    79     cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
    80 
    81     /*swap*/
    82     cout<<endl<<"swap后list的容量"<<endl;
    83     cout<<"listStr.size()    :"<<listStr.size()<<endl;
    84     cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
    85 #endif
    86     system("pause");
    87     return 0;
    88 }

    ①自己new的空间,自己delete然后再释放容器。

    ②不是new出来的,直接erase、remove和clear即可。这类链式存储,一个元素一个元素递增空间的结构,这些函数可以真正地改变list占用的内存大小。

     

    感觉好多东西啊!今天的结束了!

    参考文献:

    https://www.cnblogs.com/EE-NovRain/archive/2012/06/12/2546500.html

    https://philoscience.iteye.com/blog/1456509

    https://blog.csdn.net/a272846945/article/details/51182144

    https://blog.csdn.net/HW140701/article/details/76704583

  • 相关阅读:
    leetcode链表--15、reverse-nodes-in-k-group(按照k值进行k个结点的逆序)
    4、消除重复元素--网易2017春招
    24、剑指offer--二叉树中和为某一值的路径
    leetcode链表--14、add-two-numbers(两链表相加 得到新链表)
    3、调整队形--网易2017春招
    2、赶去公司--网易2017春招
    1、双核处理--网易2017春招
    CSS3自定义滚动条样式 -webkit-scrollbar
    git安装使用
    div+css居中
  • 原文地址:https://www.cnblogs.com/whutao/p/10609115.html
Copyright © 2011-2022 走看看