• 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是改变容器的大小,且创建对象,因此,调用这个函数之后,就可以引用容器内的对象了。

  • 相关阅读:
    跳台阶问题
    腾讯,百度,网易游戏,华为笔面经验
    进程、线程、应用程序之间的关系
    const用法小结
    vc快捷键
    文献阅读以及如何管理
    数据类型转换
    vc Debug Release
    如何阅读文献
    如何提高表达能力
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11770160.html
Copyright © 2020-2023  润新知