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

posted @ 2019-10-31 11:17  尚修能的技术博客  阅读(454)  评论(0编辑  收藏  举报