zoukankan      html  css  js  c++  java
  • vecto容器中一些没有注意到的地方

    • vector容器
      vectoor是一个单口容器。

    • vector动态增长的基本原理
      当插入新元素的时候,如果空间不足,那么vector会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间的数据,再把新元素插入新申请空间。
      vecotr这么做的原因是:vector中的元素是连续存储的,当容器中没有空间容纳新的元素,则由于元素必须连续存储以便索引访问,所以不能在内存中随便找个地方存储这个新元素,必须要开辟新的存储空间。

    • vector的data()
      之前一直没有注意到vector的data()用法,在代码片段中用到了vector的data()

    memcpy( m_arrPtData.data(), arrData.data(), iLineNum * iTriggerSize * sizeof( ushort ) );
    

    data()的函数接口如下:

          _Tp*
          data() _GLIBCXX_NOEXCEPT
          { return _M_data_ptr(this->_M_impl._M_start); }
    
          const _Tp*
          data() const _GLIBCXX_NOEXCEPT
          { return _M_data_ptr(this->_M_impl._M_start); }
    

    data()的返回值有两种,分别对应const和非const类型的指针,如:

    int main()
    {
    	vector<int> vec;
    	vec.push_back(10);
    	vec.push_back(100);
    
    	const int* cp = vec.data();
    	int* p = vec.data();
    
    	cout << *cp << endl;
    	cout << *p << endl;
    	return 0;
    }
    

    其中对于const int* cp如果有如下代码:

    *cp = 100;  //error
    

    编译器会报错:

    cp不能给常量赋值

    这其实也说明了const修饰的是*cp指向的内容,这个内容是不能被改变的。
    一个小的DEMO如下:

    int main()
    {
    	vector<int> vec;
    	vec.push_back(10);
    	vec.push_back(100);
    
    	const int* cp = vec.data();
    	int* p = vec.data();
    
    	cout << *cp << endl;
    	cout << *p << endl;
    	*p = 2;
    
    	cout << vec[1] << endl;
    	cout << *cp << endl;
    	cout << *p << endl;
    	return 0;
    }
    
    • vector的resize()和reserve()用法及区别

    出错的代码片段:

    void Net_Operator::Net_UDP_GetNaviData( std::vector<Nav1>& arrNavi1, std::vector<Nav2>& arrNavi2 )
    {
        int iSize = m_arrNavi1_b.size();
        arrNavi1.resize( iSize );
        memcpy( arrNavi1.data(), m_arrNavi1_b.data(), iSize * sizeof( Nav1 ) );
    
        iSize = m_arrNavi2_b.size();
        arrNavi2.reserve( iSize );
        memcpy( arrNavi2.data(), m_arrNavi2_b.data(), iSize * sizeof( Nav2 ) );
    }
    

    其中arrNavi2.reserve( iSize );的正确写法是arrNavi2.resize( iSize );

    出错原因如下:
    首先有代码调用上面的Net_UDP_GetNaviData()函数

            std::vector<Nav1> arrNavi1;
            std::vector<Nav2> arrNavi2;
            m_moudelNet.Net_UDP_GetNaviData( arrNavi1, arrNavi2 );
    

    注意这里的arrNavi1arrNavi2这两个vector类型的变量,其capacity都是0,size也是0,在Net_UDP_GetNaviData()函数中,arrNavi2.reserve( iSize );只是改变了arrNavi2的cacapacity,但是没有改变其size,导致后面的memcpy执行的时候,并没有把m_arrNavi2_b.data()中的内容拷贝过去,所以arrNavi2是capacity为0的vector变量,这样也就导致后序无法读取出arrNavi2中的内容。

    1.vector的capacity和size的区别
    size指的是容器当前拥有的元素个数,而capacity则指容器在必须分配新存储空间之前可以存储的元素总数。

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        vector<int> ivec;
    
        qDebug() << "ivec:size "<<ivec.size()
                 << " " << "ivec:capacity " << ivec.capacity();
    
        for(vector<int>::size_type ix = 0;ix != 24;++ix)
        {
            ivec.push_back(ix);
        }
    
        qDebug() << "ivec:size "<<ivec.size()
                 << " " << "ivec:capacity " << ivec.capacity();
    
        ivec.reserve(50);
    
        qDebug() << "ivec:size "<<ivec.size()
                 << " " << "ivec:capacity " << ivec.capacity();
    
        return a.exec();
    
    }
    

    运行结果为:

    ivec容器的当前状态如下图:

    2.resize()和reserve()的区别

    reserve是容器预留空间,但在空间内不真正创建元素对象,所以没有在添加新的对象之前,不能引用容器中的元素。
    resize是改变容器的大小,且创建对象,因此,调用这个函数之后,就可以引用容器内的对象了。

  • 相关阅读:
    【Language】 TIOBE Programming Community Index for February 2013
    【diary】good health, good code
    【web】a little bug of cnblog
    【Git】git bush 常用命令
    【web】Baidu zone ,let the world know you
    【diary】help others ,help yourself ,coding is happiness
    【Git】Chinese messy code in widows git log
    【windows】add some font into computer
    SqlServer启动参数配置
    关于sqlserver中xml数据的操作
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11770160.html
Copyright © 2011-2022 走看看