皮皮网
皮皮网

【瑞丰萝卜app源码】【小鳄鱼助手源码】【多多盘解析源码】memcopy源码

时间:2024-12-23 01:56:45 来源:91源码下载

1.用memcpy函数拷贝vector

memcopy源码

用memcpy函数拷贝vector

       定义了两个vector,vector里面存的是类,是否可以直接使用memcpy去复制vector?这个问题涉及C库函数strcpy、memcpy和memmove。让我们先了解这三种函数,然后再解答这个问题。瑞丰萝卜app源码

       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)无关。和我们实际想要复制的长度不同,会引发各种各样的qt创建线程源码错误。

       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比较

更多内容请点击【焦点】专栏