std::span

1. 有了std::span都省了些写template的功夫了

示例一:

#include <iostream>
#include <span>
#include <vector>

void printNum(std::span<int> view_contiguous_sequence){
    for(const auto it: view_contiguous_sequence){
        std::cout << it << " ";
    }
    std::cout << std::endl;
}

int main(){
    int arr[] = {1,2,3,4,5,6};
    std::span<int> view_arr(arr, 4);
    std::span<int> view_arr2(arr,2);

    printNum(arr);         // 1 2 3 4 5 6 
    printNum(view_arr);    // 1 2 3 4
    printNum(view_arr2);   // 1 2

    std::cout << std::endl;

    std::vector<int> vec{9,8,7,6,5,4,3};
    std::span<int> view_vec(vec);
    std::span<int,5> view_vec1(vec);
    std::span<int> view_vec2(vec.begin(), vec.begin() + 3);
    std::span<int> view_vec3(vec.begin(), 4);

    printNum(vec);          // 9 8 7 6 5 4 3 
    printNum(view_vec);     // 9 8 7 6 5 4 3 
    printNum(view_vec1);    // 9 8 7 6 5 
    printNum(view_vec2);    // 9 8 7 
    printNum(view_vec3);    // 9 8 7 6
}

示例二:

#include <iostream>
#include <span>
#include <vector>
#include <array>
#include <list>

struct Obj{
    void operator()(const std::span<int> contiguous_equence) const {
        for(const auto it: contiguous_equence){
            std::cout << it << " ";
        }
        std::cout << std::endl;
    }
}obj;

int main(){
    int arr[] = {0,1,2,3,4,5,6,7,8,9};
    std::vector<int> vec{1,2,3,4,5,6,7};
    std::array<int,5> arra{2,3,4,5,6};
    std::list<int> lst{3,4,5,6,7};

    std::span</*const*/ int> span1(arr, 4);

    obj(span1);   // 0 1 2 3
    obj(arr);     // 0 1 2 3 4 5 6 7 8 9
    obj(vec);     // 1 2 3 4 5 6 7
    obj(arra);    // 2 3 4 5 6
    // obj(lst);  // 不支持std::list,会报错error: no match for call to '(Obj) (std::__cxx11::list<int>&)'

    std::cout << std::endl;

    /* 修改std::span对象会修改创建std::span的对象 */
    span1[2] = 9;
    obj(span1);    // 0 1 9 3
    obj(arr);      // 0 1 9 3 4 5 6 7 8 9 
}

2. std::span并不拥有数据

类似std::string_view并不拥有数据,一定要注意std::span引用对象的有效性。

如下代码的问题是返回了局部变量arr的地址,函数调用结束后返回的地址已经无效了。

#include <iostream>

int *test(){
    int arr[] = {1,2,3};
    int *p = arr;
    return p;
}

auto main()->int{
    // g++ main.cpp -std=c++20 -fsanitize=address
    int* p = test();
    std::cout << "*p = " << *p << std::endl;
}

类似上述错误,使用std::span时务必注意要避免下述做法:

#include <iostream>
#include <span>
#include <vector>

auto main()->int{
    // g++ main.cpp -std=c++20 -fsanitize=address
    std::span<int> sp1;

    {
        std::vector<int> vec{1,2,3,4,5,6};
        sp1 = std::span<int>(vec.begin() + 1, vec.end() - 1);
    } // 打括号结束位置vec已经不存在了,但是sp1还在引用它,属于未定义行为,多线程下更容易发现问题

    for(const auto&it: sp1){
        // 每次输出的值可能都不一样
        std::cout << it << " ";  // 0 1884814536 284698390 5
    }
    std::cout << std::endl;
}

上述代码编译后,运行报错如下:

=================================================================
==1==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000044 at pc 0x0000004018b4 bp 0x7fff0ad7fb30 sp 0x7fff0ad7fb28
READ of size 4 at 0x603000000044 thread T0
    #0 0x4018b3 in main /app/example.cpp:36
    #1 0x71a82be29d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 962015aa9d133c6cbcfb31ec300596d7f44d3348)
    #2 0x71a82be29e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: 962015aa9d133c6cbcfb31ec300596d7f44d3348)
    #3 0x401204 in _start (/app/output.s+0x401204) (BuildId: 04a33e88cc2a9de560eb5e605daa0a9d7522f39e)

0x603000000044 is located 4 bytes inside of 24-byte region [0x603000000040,0x603000000058)
freed by thread T0 here:
    #0 0x71a82c4b6a78 in operator delete(void*, unsigned long) (/opt/compiler-explorer/gcc-13.2.0/lib64/libasan.so.8+0xdda78) (BuildId: 53df075b42b04e0fd573977feeb6ac6e330cfaaa)
    #1 0x403730 in std::__new_allocator<int>::deallocate(int*, unsigned long) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/new_allocator.h:168
    #2 0x403256 in std::allocator<int>::deallocate(int*, unsigned long) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/allocator.h:210
    #3 0x403256 in std::allocator_traits<std::allocator<int> >::deallocate(std::allocator<int>&, int*, unsigned long) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/alloc_traits.h:516
    #4 0x403256 in std::_Vector_base<int, std::allocator<int> >::_M_deallocate(int*, unsigned long) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_vector.h:387
    #5 0x402712 in std::_Vector_base<int, std::allocator<int> >::~_Vector_base() /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_vector.h:366
    #6 0x402881 in std::vector<int, std::allocator<int> >::~vector() /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_vector.h:735
    #7 0x40179d in main /app/example.cpp:32
    #8 0x71a82be29d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 962015aa9d133c6cbcfb31ec300596d7f44d3348)

previously allocated by thread T0 here:
    #0 0x71a82c4b5b78 in operator new(unsigned long) (/opt/compiler-explorer/gcc-13.2.0/lib64/libasan.so.8+0xdcb78) (BuildId: 53df075b42b04e0fd573977feeb6ac6e330cfaaa)
    #1 0x4027e3 in std::__new_allocator<int>::allocate(unsigned long, void const*) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/new_allocator.h:147
    #2 0x402543 in std::allocator<int>::allocate(unsigned long) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/allocator.h:198
    #3 0x402543 in std::allocator_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/alloc_traits.h:482
    #4 0x402543 in std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_vector.h:378
    #5 0x401f1a in void std::vector<int, std::allocator<int> >::_M_range_initialize<int const*>(int const*, int const*, std::forward_iterator_tag) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_vector.h:1689
    #6 0x401b94 in std::vector<int, std::allocator<int> >::vector(std::initializer_list<int>, std::allocator<int> const&) /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_vector.h:679
    #7 0x4015d2 in main /app/example.cpp:30
    #8 0x71a82be29d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: 962015aa9d133c6cbcfb31ec300596d7f44d3348)

SUMMARY: AddressSanitizer: heap-use-after-free /app/example.cpp:36 in main
Shadow bytes around the buggy address:
  0x602ffffffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x602ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x602ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x602fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x602fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x603000000000: fa fa 00 00 00 fa fa fa[fd]fd fd fa fa fa fa fa
  0x603000000080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x603000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1==ABORTING

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【后端】websocket学习笔记

文章目录 1. 消息推送常见方式1.1 轮询 VS 长轮询1.2 SSE&#xff08;server-sent event)服务器发送事件 2. websocket介绍2.1 介绍2.2 原理2.3 websoket API2.3.1 客户端【浏览器】API2.3.2 服务端API 3. 代码实现3.1 流程分析3.2 pom依赖3.3 配置类3.4 消息格式3.5 消息类 参…

【Css】纯css展开、收起超出的文本

效果 展开 收起 未超出 码 -webkit-line-clamp: 3; 设置限制行数 <div class"wrap"> <inputtype"checkbox"id"exp-txt"><div class"text"><labelfor"exp-txt"class"btn"></label&g…

纷享销客常见问题FAQ

运维和安全职责边界 应用专属是部署在客户私有云或者客户公有云租户的IT环境中的&#xff0c;由纷享销客与客户共同维护系统的稳定性。一般来说客户主要负责维护IT基础环境和账号权限的管理而纷享销客则负责在客户环境中进行应用系统的部署、优化和日常运维工作。在安全方面&am…

OrangePi AIpro 机器人仿真与人工智能应用测评

系列文章目录 前言 本篇文章分为2个部分&#xff0c;第一部分主要搭建了机器人的仿真环境&#xff08;ROS2 MuJoCo等&#xff09;&#xff0c;运行了机械臂及移动机器人相关示例程序&#xff1b;第二部分运行了OrangePi AIpro系统自带的示例程序及昇腾社区官方的示例程序&#…

马克·雷伯特访谈:机器人的未来及波士顿动力的创新之路

引言 机器人技术作为现代科技的前沿领域&#xff0c;始终吸引着大量的关注与研究。波士顿动力公司作为这一领域的领军者&#xff0c;其创始人兼前CEO马克雷伯特&#xff08;Marc Raibert&#xff09;近日在主持人莱克斯弗里德曼&#xff08;Lex Fridman&#xff09;的播客节目…

机器学习笔记 - 用于3D点云数据分割的Point Net的训练

一、数据集简述 ​在本教程中,我们将学习如何在斯坦福 3D 室内场景数据集 ( S3DIS )上训练 Point Net 进行语义分割。S3DIS 是一个 3D 数据集,包含来自多栋建筑的室内空间点云,占地面积超过 6000 平方米。Point Net使用整个点云,能够执行分类和分割任务。如果你一直在关注 …

【归并排序】| 详解归并排序核心代码之合并两个有序数组 力扣88

&#x1f397;️ 主页&#xff1a;小夜时雨 &#x1f397;️专栏&#xff1a;动态规划 &#x1f397;️如何活着&#xff0c;是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/merge-sorted-array/description/ 本道题是归并排序的…

SNAT和DNAT策略

1、SNAT策略及应用 SNAT应用环境&#xff1a;局域网主机共享单个公网IP地址接入Internet&#xff08;私有不能在Internet中被正常路由&#xff09; SNAT原理&#xff1a; 修改数据包的源地址。 SNAT转换前提条件&#xff1a; 局域网各主机已正确设置IP地址、子网掩码、默认…

库的制作 与 使用 (Linux下)

目录 动静态库的制作 前置知识 库的基本构造 问题 分析 要给什么文件 如何更好的让别人使用 库的生成 静态库的生成 makefile参考 动态库的生成 makefile参考&#xff08;包含动态库和静态库生成&#xff09; 库的使用 法一&#xff1a;放入系统路径 弊端 法二…

Android开发系列:高性能视图组件Surfaceview

一、Surfaceview概述 在Android应用开发领域&#xff0c;面对视频播放、游戏构建及相机实时预览等高性能需求场景&#xff0c;直接操控图像数据并即时展示于屏幕成为必要条件。传统View组件在此类情境下显现局限性&#xff1a; 性能瓶颈&#xff1a;传统View的绘制任务由UI主…

如何充分利用 Postgres 的内存设置

为了充分利用 PostgreSQL 的内存设置&#xff0c;你需要调整多个参数以优化数据库性能。这些参数包括共享缓冲区&#xff08;shared_buffers&#xff09;、工作内存&#xff08;work_mem&#xff09;、维护工作内存&#xff08;maintenance_work_mem&#xff09;、有效缓存大小…

命令词:引导行动的语言工具

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

《全职猎人》

《全职猎人》 [1-2]是日本漫画家富坚义博的作品。 1999年版改编电视动画由日本动画公司负责动画制作&#xff0c;于1999年10月16日&#xff0d;2001年3月30日在富士电视台播出&#xff0c;该动画的故事至贪婪之岛篇章结束&#xff0c;全92话。 该作在富坚义博老师天马行空的想…

markupsafe,一个神奇的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个神奇的 Python 库 - markupsafe。 Github地址&#xff1a;https://github.com/pallets/markupsafe 在 Web 开发和模版渲染中&#xff0c;处理用户输入的数据时&#xff0c;防止 HTML 注入是至…

【Java】Object、Objects、包装类、StringBuilder、StringJoiner

目录 1.API2.Object类3.Objects类4.包装类4.1包装类概述4.2包装类的其他常见操作 5.StringBuilder 可变字符串5.1概述5.2StringBuilder案例 6.StringJoiner 1.API API&#xff1a;应用程序编程接口&#xff0c;全称application programing interface&#xff0c;即Java已经写好…

3分钟带手把手带你了解 FL Studio v21.2.3.4004 中文免费版(附中文设置教程)安装指南

3分钟带手把手带你了解 FL Studio v21.2.3.4004 中文免费版(附中文设置教程)安装指南&#xff0c;大家我是兔八哥爱分享&#xff0c;今天你带来的安装FL Studio 21破解版&#xff0c;纯正简体中文支持&#xff01; FL Studio 21 简称FL21&#xff0c;全称Fruity Loops Studio&a…

消息队列-Rabbit运行机制

Producer(生产者) 和 Consumer(消费者) Producer(生产者) :生产消息的一方&#xff08;邮件投递者&#xff09;Consumer(消费者) :消费消息的一方&#xff08;邮件收件人&#xff09; 消息一般由 2 部分组成&#xff1a;消息头&#xff08;或者说是标签 Label&#xff09;和 …

keystone认证服务

keystone认证服务 1、keystone管理用户 1-1、简介&#xff1a; 在OpenStack云计算平台中&#xff0c;Keystone是一个核心组件&#xff0c;主要用于提供统一的认证服务。其功能包括&#xff1a; 身份验证&#xff1a;Keystone负责验证用户的身份&#xff0c;通常通过用户名和…

记录一个flink跑kafka connector遇到的问题

【报错】 D:\Java\jdk1.8.0_231\bin\java.exe "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2022.2.3\lib\idea_rt.jar56647:D:\Program Files\JetBrains\IntelliJ IDEA 2022.2.3\bin" -Dfile.encodingUTF-8 -classpath D:\Java\jdk1.8.0_231\jre\lib\cha…

本学期嵌入式期末考试的综合项目,我是这么出题的

时间过得真快&#xff0c;临近期末&#xff0c;又到了老师出卷的时候。作为《嵌入式开发及应用》这门课的主讲教师&#xff0c;今年给学生出的题目有一点点难度&#xff0c;最后的综合项目要求如下所示&#xff0c;各位学生朋友和教师同行可以评论一下难度如何&#xff0c;单片…