【c++随笔16】reserve之后,使用std::copy会崩溃?

【c++随笔16】reserve之后,使用std::copy会崩溃?

  • 一、reserve之后,使用std::copy会崩溃?
  • 二、函数std::reserve、std::resize、std::copy
    • 1、std::resize:
    • 2、std::reserve:
    • 3、std::copy:
  • 三、崩溃原因分析
    • 方案1、你可以使用 std::back_inserter 插入迭代器来向 destination 中插入元素,代码如下:
    • 方案2、resize将容器大小调整同时,新增的元素将会被默认初始化为0,这样std::copy中的destination.begin()就可用访问到元素了

原创作者:郑同学的笔记
原创地址:https://zhengjunxue.blog.csdn.net/article/details/134272501

一、reserve之后,使用std::copy会崩溃?

先看代码

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> source = { 1, 2, 3, 4, 5 };std::vector<int> destination;// 在目标vector中预留足够的空间,避免不必要的重新分配destination.reserve(source.size());// 使用std::copy将source中的元素复制到destination中std::copy(source.begin(), source.end(), destination.begin());// 打印复制后的destination内容for (int num : destination) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

运行,崩溃截图如下
在这里插入图片描述

我们先简单说下std::reserve、std::resize、std::copy三个函数的用法,然后再说崩溃的原因。

二、函数std::reserve、std::resize、std::copy

1、std::resize:

  • std::resize 用于改变容器的大小,并可以指定新元素的初值。
  • 如果新的大小大于当前大小,则在末尾添加新元素;如果新的大小小于当前大小,则删除多余的元素。
  • 使用 resize 会改变容器内的元素个数,并可能导致元素值的改变。

示例代码如下:

std::vector<int> vec = {1, 2, 3};
vec.resize(5); // 将容器大小调整为 5,新增的元素将会被默认初始化为0
vec.resize(3); // 将容器大小调整为 3,多余的元素将会被删除

2、std::reserve:

  • std::reserve 用于预留容器的空间,但不会改变容器的大小。
  • 当你知道容器将要存储大量元素时,可以使用 reserve 来提前分配足够的内存,避免容器多次扩张操作。
  • 使用 reserve 不会改变容器中的元素个数,只是预分配了足够的空间。

示例代码如下:

std::vector<int> vec;
vec.reserve(100); // 预留至少能容纳100个元素的空间

3、std::copy:

template <class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result);

std::copy 用于将一个范围内的元素复制到另一个范围,它可以用于将一个容器中的元素复制到另一个容器中

注意事项

  • 确保输出范围有足够的空间来容纳被复制的元素,否则可能会导致未定义的行为。
  • 当处理容器时,确保输出容器有足够的容量,或者使用插入迭代器(如 std::back_inserter)来确保动态分配足够的空间。
int source[] = {1, 2, 3, 4, 5};
int destination[5];// 使用 std::copy 将 source 数组的内容复制到 destination 数组
std::copy(std::begin(source), std::end(source), std::begin(destination));

三、崩溃原因分析

  • 在这个代码中,当你使用 std::copy 将 source 中的元素复制到 destination 中时,会导致程序崩溃的原因是因为 destination 容器的空间虽然预留了,但是其中并没有实际的元素,所以无法直接通过 destination.begin() 来访问 destination 的首个元素。

  • 在使用 std::copy 进行复制时,目标容器必须有足够的空间来容纳被复制的元素,并且使用 std::back_inserter 或者确保目标容器大小与源容器相同的方式来进行插入操作。如果目标容器没有足够的空间或者没有正确的插入迭代器,就会导致未定义的行为,可能导致程序崩溃。

要修复这个问题,有两个方法你可以使用

方案1、你可以使用 std::back_inserter 插入迭代器来向 destination 中插入元素,代码如下:

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> source = { 1, 2, 3, 4, 5 };std::vector<int> destination;// 在目标vector中预留足够的空间,避免不必要的重新分配destination.reserve(source.size());// 使用std::copy将source中的元素复制到destination中std::copy(source.begin(), source.end(), std::back_inserter(destination));// 打印复制后的destination内容for (int num : destination) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

方案2、resize将容器大小调整同时,新增的元素将会被默认初始化为0,这样std::copy中的destination.begin()就可用访问到元素了

#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> source = { 1, 2, 3, 4, 5 };std::vector<int> destination;// 在目标vector中预留足够的空间,避免不必要的重新分配destination.resize(source.size());// 使用std::copy将source中的元素复制到destination中std::copy(source.begin(), source.end(), destination.begin());// 打印复制后的destination内容for (int num : destination) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/264445.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于以太坊的智能合约开发Solidity(基础篇)

参考教程&#xff1a;基于以太坊的智能合约开发教程【Solidity】_哔哩哔哩_bilibili 1、第一个程序——Helloworld&#xff1a; //声明版本号&#xff08;程序中的版本号要和编译器版本号一致&#xff09; pragma solidity ^0.5.17; //合约 contract HelloWorld {//合约属性变…

JAVA高级(后端需深入移步)

单元测试&#xff1a;使用Junit单元测试框架 使用Junit单元测试&#xff1a; 通过左侧的对❌来进行提示 Junit框架的常见注解&#xff1a; 反射&#xff08;用于框架&#xff0c;也是最重要&#xff09;&#xff1a;展示框架的成员信息 由于是用于对象&#xff0c;即使在获取…

12.视图

目录 1.视图的含义与作用 2.视图的创建与查看 1.创建视图的语法形式 2、查看视图&#xff1a; 1.使用DESCRIBE语句查看视图基本信息 2.使用SHOW TABLE STATUS语查看视图基本信息查看视图的信息 3.使用SHOW CREATE VIEW语查看视图详细信息 4.在views表中查看视图详细信息…

西南科技大学C++程序设计实验七(继承与派生二)

一、实验目的 1. 掌握多继承程序设计 2. 掌握虚基类编程 3. 拓展学习可视化程序设计中的继承与派生应用 二、实验任务 重点:掌握虚基类的定义与实现,拓展其功能。 阅读分析、完善程序。下面程序(1)与程序(2)分别是没有使用虚基类和使用虚基类的代码,其中A是最上层基…

java实现网络聊天

网络聊天实现步骤&#xff08;从功能谈论方法&#xff09;&#xff1a; 客户端&#xff1a; 1.登录面板&#xff1a;注册提醒用户注册格式&#xff0c;登录账号密码不为空&#xff0c;点击登录的时候需要连接服务器端&#xff0c;启动聊天面板。&#xff08;监听用户点击登录…

MySQL - InnoDB 和 MyISAM 的索引实现的区别

InnoDB 和 MyISAM 底层都是 B 树的实现&#xff0c;但是二者却完全不同 。 主键索引文件存储不同 MyISAM 引擎的索引文件和数据文件是分离的&#xff0c;而 InnoDB 引擎的索引文件和数据文件是不分离的。 MyISAM 引擎的叶子节点存储的是数据文件的地址&#xff0c;而 InnoDB 的…

unity 2d 入门 飞翔小鸟 死亡闪烁特效(十三)

一、c#脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Bling : MonoBehaviour {public Texture img;public float speed;public static bool changeWhite false;private float alpha0f;// Start is called before the fi…

【STM32】关于H743中出现的ANA类型引脚

最近调试H743ZI这个封装的H743的LAN8720功能 LAN8720是需要用一个外部引脚进行外部复位的 之前也没有好好看手册&#xff0c;选了PC2_C来做这个输出低电平复位信号的IO口 但是重点来了&#xff0c;PC2_C其实它不能做普通IO口&#xff0c;无法控制其输出高低电电平)!!! 手册上写…

nodejs微信小程序+python+PHP在线学习平台设计与实现-计算机毕业设计推荐

概念模型是对现实中的问题出现的事物的进行描述&#xff0c;ER图是由实体及其关系构成的图&#xff0c;通过E-R图可以清楚地描述系统涉及到的实体之间的相互关系。 困扰管理层的许多问题当中,在线学习也是不敢忽视的一块。但是管理好在线学习又面临很多麻烦需要解决,例如&…

流水号的获取

软件中&#xff0c;常常使用流水号&#xff0c;通常流水号是一组参数的组合&#xff0c;如&#xff1a;评估报告的编号结构&#xff1a; 区编号-机构类型-年份-性别-流水 如&#xff1a;03-01-2023-W-0001 03-01-2023-M-0002 03-01-2023-M-0003 。。。。。。 编程时&#xff0c…

有病但合理的 ChatGPT 提示语

ChatGPT 面世一年多了&#xff0c;如何让大模型输出高质量内容&#xff0c;让提示词工程成了一门重要的学科。以下是一些有病但合理的提示词技巧&#xff0c;大部分经过论文证明&#xff0c;有效提高 ChatGPT 输出质量&#xff1a; ​1️⃣ Take a deep breath. 深呼吸 ✨ 作用…

Threejs发光闪烁提示特效

一、导语 发光闪烁特效应该在我们的项目中是经常需要去封装的一个特效吧&#xff0c;一般用于点击选择&#xff0c;选中物体&#xff0c;或者一些特效加持于中心物体&#xff0c;物体碰撞检测后的发光特效等等 二、分析 我们可以合理的使用后处理特效&#xff0c;上步骤&am…