网络科技公司网站首页说一说网站建设的含义
news/
2025/10/6 18:05:04/
文章来源:
网络科技公司网站首页,说一说网站建设的含义,西安网站制作公司排名,广东网站制作设计送给大家一句话#xff1a;
世界在旋转#xff0c;我们跌跌撞撞前进#xff0c;这就够了 —— 阿贝尔 加缪 vector问题解决 1 前言2 迭代器区间拷贝3 迭代器失效问题4 memcpy拷贝问题 1 前言
我们之前实现了手搓vector#xff0c;但是当时依然有些问题没有解决#xff… 送给大家一句话
世界在旋转我们跌跌撞撞前进这就够了 —— 阿贝尔 加缪 vector问题解决 1 前言2 迭代器区间拷贝3 迭代器失效问题4 memcpy拷贝问题 1 前言
我们之前实现了手搓vector但是当时依然有些问题没有解决
迭代器区间拷贝非法的间接寻址问题迭代器失效问题使用memcpy拷贝问题
接下来我们一点一点来解决这些问题
2 迭代器区间拷贝
来看这个这个构造函数 templateclass InputIteratorvector(InputIterator first, InputIterator last){while (first ! last){push_back(*first);first;}}这个是对迭代器区间进行的构造函数思路很简单把迭代器区间的数据依次尾插就可以了这里之所以另外使用一个新的模版而不是使用vector类的模版是为了兼容更多的数据类型。这样就可以通过一个现有的类型来构造容器。 但是出乎意料的是出现了一个问题 C2100 非法的间接寻址 编译层面的问题 。非法的间接寻址的造成原因有很多
空指针引I用当一个指针没有被初始化或者为NULL时对它进行间接寻址操作会导致非法访问。野指针引用当一个指针超出了它所指向的内存范围或者已经被释放但仍然被引用时进行间接寻址操作也会导致非法访问。类型不匹配如果试图将指针转换为不兼容的类型进行间接寻址也会导致非法访问。
我们分析一下我们遇到的问题是那种问题空指针引用吗不可能野指针引用吗也不可能 那么真相只有一个我们遇到了类型不匹配的问题那这是来自哪里的呢经过我的排除法注释不同的代码块来进行查找得到了结果
vectorint v1(5,6);这一行代码是我们出错的根源为什么这个构造没有去使用vector(size_t n,T val T()),而是使用我们的vector(InputIterator first, InputIterator last),因为第二个函数与5,6的类型更匹配编译器会寻找最合适的函数。
解决方法也是十分暴力多枚举几个 构造函数
vector(size_t n,T val T())
vector(int n,T val T());
vector(long long n,T val T());这样就会优先匹配vector(int n,T val T());了我们的问题也就解决了。
3 迭代器失效问题
这个问题主要出现在我们的插入操作insert和删除操作(erase)。来看
void vector_test7() {vectorint v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);v1.push_back(7);vectorint::iterator it v1.begin() 3;// 4cout *it endl;v1.insert(3, 40);cout *it endl;
}这个执行的结果是 迭代器的指向发生了改变我们实现的迭代器的底层是指针我们插入之后指针位置不变而数组元素改变自然会产生不一样的结果。这个问题看起来不严重那我们再来看
void vector_test7() {vectorint v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);v1.push_back(7);v1.push_back(8);vectorint::iterator it v1.begin() 3;// 4cout *it endl;v1.insert(3, 40);cout *it endl;
}为什么这里出现了乱码我们代码和之前的区别是什么一个进行了扩容一个没进行扩容。扩容之后vector的_start发生了改变自然我们的指针也失去了对应作用。 迭代器就失效了这个解决办法也很简单就是插入之后不要使用之前的迭代器一定要对迭代器进行更新。
再来看erase中的问题
void vector_test7() {vectorint v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);//v1.push_back(6);//v1.push_back(7);//v1.push_back(8);vectorint::iterator it v1.begin();//删除偶数while (it ! v1.end()){if (*it % 2 0){v1.erase(it);}it;}print_vector(v1);
}这样运行起来是没有问题的那么再来看
void vector_test7() {vectorint v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(4);v1.push_back(5);//v1.push_back(6);//v1.push_back(7);//v1.push_back(8);vectorint::iterator it v1.begin();//删除偶数while (it ! v1.end()){if (*it % 2 0){v1.erase(it);}it;}print_vector(v1);
}现在出现了 这个问题问题的来源也很简单我们迭代器在删除之后没有改变位置但是_start的元素发生了改变也就是相当于 it 向后移动了两次为了避免这个情况我们可以 while (it ! v1.end()){if (*it % 2 0){v1.erase(it);}else{it;}}这样就可以了 需要注意的一点是我们的操作是以g标准来进行的如果删除会进行缩容也会出现错误迭代器就不能进行了所以 在VS环境下vector 容器在erase 之后的迭代器是严格不能使用的使用就会报错,因为VS迭代器的底层不是原生指针判断有所不同。 迭代器失效解决方案总结 1. 删除插入之后更新对应迭代器erase删除后会返回新的迭代器 按规则进行迭代就可以了 it v1.erase(it) 2. 插入删除之后不使用迭代器
4 memcpy拷贝问题
我们创建一个string类的容器来看看能不能正常运行
void vector_test8() {vectorstring v1;v1.push_back(11111);v1.push_back(22222);v1.push_back(33333);v1.push_back(44444);v1.push_back(55555);print_vector(v1);
}来看效果 程序直接崩掉了经过我们的调试我们能打印出来正确的数据但是走到程序最后的时候出现了错误那么应该就是析构函数的问题了 来画图分析一波
memcpy是内存的二进制格式拷贝将一段内存空间中内容原封不动的拷贝到另外一段内存空间中如果拷贝的是自定义类型的元素memcpy既高效又不会出错但如果拷贝的是自定义类型元素并且自定义类型元素中涉及到资源管理时就会出错因为memcpy的拷贝实际是浅拷贝。
结论如果对象中涉及到资源管理时千万不能使用memcpy进行对象之间的拷贝因为memcpy是浅拷贝否则可能会引起内存泄漏甚至程序崩溃
那么怎么解决呢非常简单 //扩容void reserve(size_t newcapacity) {//记录位置size_t n _finish - _start;T* tmp new T[newcapacity];//拷贝//memcpy(tmp, _start, size() * sizeof(T));for (size_t i 0; i size(); i){tmp[i] _start[i];}delete[] _start;_start tmp;_finish _start n;_end _start newcapacity;}不使用memcpy函数不就可以了然后我们使用简单粗暴的赋值拷贝这样就不会发生浅拷贝问题了
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/929578.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!