1.用memcpy函数拷贝vector
用memcpy函数拷贝vector
定义了两个vector,实现vector里面存的源码是类,是实现否可以直接使用memcpy去复制vector?这个问题涉及C库函数strcpy、memcpy和memmove。源码让我们先了解这三种函数,实现然后再解答这个问题。源码mitoq溯源码
1. strcpy,实现 memcpy以及memmove
strcpy, memcpy, memmove都是C库函数,它们的源码原型如下:
strcpy 不需要传入复制的字节数,而memcpy和memmove需要,实现这是源码因为memcpy和memmove需要明确知道要复制的字节数。
2. 用memcpy函数拷贝vector
分步骤来考虑这个问题。实现
2.1 初探
我们先考虑vector存放内置类型的源码情况。不同于数组,实现vector对象在使用时不会转换成指针,源码因此,实现需要使用取地址符&来得到vector对象的地址。
执行上述代码后,我们发现test1中元素的地址可以正常输出。
然而,当程序退出时,引发"读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突"的枪战游戏源码异常,这是为什么呢?我们可以发现,test1中元素的地址和test中的是相同的!那么,我们可以做出如下猜测:
当程序退出时,后声明的test1先被释放。轮到test调用其析构函数释放内存时,其中的元素在test1释放时就已经被释放,再尝试访问这些元素进行内存释放会引发“访问冲突”的异常。
那应该怎么做呢?
我们先给test1分配空间,并默认初始化:
然后,新闻源源码将复制语句改成
此时程序正常运行并正常退出。我们用&test[0], &test1[0]真正地取到了test, test1的首元素的地址,函数按照顺序将test中的元素复制到test1中。
注意:不能写成 的形式,因为sizeof(test)得到的是vector的大小,这是一个固定值,和其中存储的值的数量、类型(除了bool)无关。和我们实际想要复制的长度不同,会引发各种各样的族谱网源码错误。
2.2 进一步探索
考虑vector存放类类型的情况。定义一个MyClass类,执行下列语句,确实先析构了test1中的元素,等到test调用其析构函数时,访问冲突异常。按照第一章中的方式进行修改,变量正常析构,程序正常退出。
注意:
2.3 更进一步
之前提到,苹果游戏源码STL容器占的字节数和储存的数据的数目和类型(除了bool)无关,是一个固定值。用vector举例,网上很多回答都是说vector中有三个迭代器变量:start, finish, end_of_storage。这三个迭代器的类型是type* 类型指针。因此vector的大小是固定的,在位机上是(debug版本),在位机上是(debug版本)。
并且有说vector::begin()函数返回start;vector::end()函数返回finish... 不知道是不是版本或者编译器的问题,至少在我在vs中,sizeof(vector)的结果有多种,尝试了一些常见的类型:
观察上述运行结果,除了bool很特殊之外,其他的似乎和上述说法吻合。然而,当我执行下列语句时:
得到的结果为:
只有当type不为bool且在release版本下才满足上述说法。
2.3.1 bool类型的特殊之处
bool类型的变量占1个字节,但是bool类型只有两个取值false和true. 因此,为了提高效率,在vector中,bool变量是按位储存的。为了实现这一优化,vector除了有一般vector的成员变量外,还有两个额外的成员变量:
在位机上,这两个变量都占8个字节,因此在debug版本下,vector比vector多占个字节。release版本下可能只有其中一个变量,具体是哪个我也还不清楚。
一般的vector对象在使用[]运算符时, 返回一个类型为OtherType&的左值;而vector对象访问一个代理引用(proxy reference)而非真正的引用(true reference),并返回一个类型为_Vb_reference<_Wrap_alloc > >的右值,因此不能用该返回值初始化一个bool&:
虽然vb[0]不是一个左值,但是仍然可以通过修改它的值来修改vb:
2.3.2 一般的vector
一种说法是:一般的vector只有一个迭代器:_Compressed_pair<_Alty, _Scary_val> _Mypair,它在位机器上占个字节,begin(),end()函数都返回它。因此debuge版本下sizeof(vector::begin())的值为. 这种说法仅供参考。
参考链接:
STL源码剖析-vector
谈vector的特殊性——为什么它不是STL容器
c语言中memcpy是字节大小, 使用memcpy函数时要注意拷贝数据的长度
C++之strcpy、memcpy、memmove比较