STL vector与数组的互转

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Sagittarius_Warrior/article/details/54089242

    C++ STL库中vector素有动态数组的美誉,为什么?我想有以下几个原因:

1)它能够弥补普通数组(如“int a[8]”)只能固定长度的缺陷;

2)它能弥补一般堆数组(如int *p = new int[n])需要预先知道长度,并且长度不可变的缺陷。

    在有些情况下,比如从文件中读取一组未知长度的float型的数据。

3)相对STL中其他容器,如list,vector与数组更接近,它内部的数据存储在一片连续的存储空间,访问效率会更高;而list是链表,数据在存储空间上不相邻。


    vector的“动态数组”的美誉的另一体现是,它与数组的灵活互转。

一、数组转vector

    利用vector的构造函数,可以很方便的将数组转为vector。例如:

    float arrHeight[] = { 1.68,1.72,1.83,2.05,2.35,1.78,2.1,1.96 };
    vector<float> vecHeight(arrHeight, arrHeight+sizeof(arrHeight)/sizeof(float));

    参考官方文档:http://www.cplusplus.com/reference/vector/vector/

    关于vector的构造,有如下几种:

default (1)
explicit vector (const allocator_type& alloc = allocator_type());
fill (2)
explicit vector (size_type n);
         vector (size_type n, const value_type& val,
                 const allocator_type& alloc = allocator_type());
range (3)
template <class InputIterator>
  vector (InputIterator first, InputIterator last,
          const allocator_type& alloc = allocator_type());
copy (4)
vector (const vector& x);
vector (const vector& x, const allocator_type& alloc);
move (5)
vector (vector&& x);
vector (vector&& x, const allocator_type& alloc);
initializer list (6)
vector (initializer_list<value_type> il,
       const allocator_type& alloc = allocator_type());

    上述例子用的就是第三种,range构造函数。我在VS2015下进行了实验,通过查看内存,可以发现,vecHeight的数据部分的内存地址和arrHeight是相同的,也就是说,上述例子中,没有真正进行数据拷贝,这里应该是用到了“写时复制”的技术,提高了数据复制的效率。

    此外,可以参考博客:http://www.cnblogs.com/mr-wid/archive/2013/01/22/2871105.html


二、vector转数组

    由于vector内部的数据是存放在连续的存储空间,vector转数组事实上只需要获取vector中第一个数据的地址和数据的长度即可。如果仅仅是传参,无需任何操作,直接传地址即可,如果要进行数据复制,可以借用内存拷贝函数“memcpy”。例如:

    float *buffer = new float[vecHeight.size()];
    if (!vecHeight.empty())
    {
        memcpy(buffer, &vecHeight[0], vecHeight.size()*sizeof(float));
    }

    本段参考博客:http://nianning1981.blog.163.com/blog/static/3083014320103171299619/


三、应用建议

1,vector作为动态数组,它的实现方法是:预先分配一个内存块,当感觉不够用的时候,再分配一个更大的内存块,然后自动将之前的数据拷贝到新的内存块中。

所以,出于效率考虑,如果实现知道待存储的数据长度,可以使用resize函数开辟足够的内存,避免后续的内存拷贝。

2,如果数组的元素是字符,建议使用string,而不是vector<char>。


附两篇博文,谈vector等容器的效率问题:

http://www.cnblogs.com/smiler/p/4457622.html

http://www.cppblog.com/sailing/articles/161659.html


展开阅读全文

没有更多推荐了,返回首页