c++ vector下标_vectorat

c++ vector下标_vectoratC语言(加了层语法糖的汇编)为了性能并不支持数组的越界检查,每次检查会多付出2-3倍的时间。而vector以at的形式支持越界检查,但也支持C语言风格的[]高效访问,没错C++提供了足够的自由。当要获取std::vector的第n个元素,下面几种方式都可以:  std::vector<int>vec; size_tn=1; in…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

C语言(加了层语法糖的汇编)为了性能并不支持数组的越界检查,每次检查会多付出2-3倍的时间。

而vector以at的形式支持越界检查,但也支持C语言风格的[]高效访问,没错C++提供了足够的自由。

当要获取 std::vector 的第 n 个元素,下面几种方式都可以:

 
  1. std::vector<int> vec;

  2. size_t n = 1;

  3. int & i = vec[n];

  4. int & j = *(vec.begin() + n);

  5. int & k = vec.at(n);

但是如果 n 超过了 vector 的下标范围,在几种方式的结果就有区别了。

在 linux 平台只有 at(n) 会抛出 std::out_of_range 异常,而其他两个都不会。

 查看标准模板库代码,可以看到:

 
  1. // element access

  2. /**

  3. * @brief Subscript access to the data contained in the %vector.

  4. * @param n The index of the element for which data should be

  5. * accessed.

  6. * @return Read/write reference to data.

  7. *

  8. * This operator allows for easy, array-style, data access.

  9. * Note that data access with this operator is unchecked and

  10. * out_of_range lookups are not defined. (For checked lookups

  11. * see at().)

  12. */

  13. reference

  14. operator[](size_type __n)

  15. { return *(this->_M_impl._M_start + __n); }

有说明:通过 operator[] 获取数组元素,不会检查下标有效性,需要检查的时候使用 at 接口

在 windows 平台 VS 环境下,都会抛出异常,VC 下的标准库是这样现实的:

 
  1. reference operator[](size_type _Pos)

  2. { // subscript mutable sequence

  3.  
  4. #if _HAS_ITERATOR_DEBUGGING

  5. if (size() <= _Pos)

  6. {

  7. _DEBUG_ERROR("vector subscript out of range");

  8. _SCL_SECURE_OUT_OF_RANGE;

  9. }

  10. #endif /* _HAS_ITERATOR_DEBUGGING */

  11. _SCL_SECURE_VALIDATE_RANGE(_Pos < size());

  12.  
  13. return (*(_Myfirst + _Pos));

  14. }

在 Debug 配置下, _HAS_ITERATOR_DEBUGGING 默认定义为 1,但是即使强制定义为 0,也有异常,因为还有一个 _SCL_SECURE_VALIDATE_RANGE 检查。所以即使在 Release 配置下,下标检查也是存在的。

如果把上面的代码中的“引用”符号去掉,像这样:

 
  1. std::vector<int> vec;

  2. size_t n = 1;

  3. int i = vec[n];

  4. int j = *(vec.begin() + n);

  5. int k = vec.at(n);

那么 at(n) 仍然会抛出 std::out_of_range 异常,其他两个会出现什么情况呢,也许是内存访问异常,也许是其他诡异的错误。

在 vec 非空的情况下,即使下标越界,也有可能对应的内存是可读写的,至于读到的是什么内容,或者写到什么地方,就是随机事件了。

所以尽量用 at 接口,让错误尽早暴露出来。

源链接:https://blog.csdn.net/luansxx/article/details/10194171

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/188404.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 输入代码自动生成名称_变量命名工具codelf

    输入代码自动生成名称_变量命名工具codelfCodeifCodeIfhttps://unbug.github.io/codelf/包含流行语言,java,c,javaScript,python等等

    2022年9月21日
    3
  • 二叉树的三叉存储

    二叉树的三叉存储

    2022年1月23日
    38
  • ASP.net错误:Control’ctl00_ctl00_ContentPlaceHolder2[通俗易懂]

    ASP.net错误:Control’ctl00_ctl00_ContentPlaceHolder2[通俗易懂]表现:当然也可能是另外一个什么控件必须放置在Form里边。原因:如果是普通情况,当然直接加一个Form就可以了,但如果是使用了masterpage,这个错误的真正原因是在masterpage中ContentPlaceHolder被错误放置到<form>外面了:<formid=”form1″runat=”server”&g…

    2022年7月13日
    17
  • Java把string转json格式_java实体类转json字符串

    Java把string转json格式_java实体类转json字符串做项目时遇到一个错误:其实这个错误也是一种广义的序列化错误,指将对象转换为JSON格式的字符串出现异常;狭义的序列化指:将对象转换为字节反序列化指:将字节转换成对象★Java对象—–>JSON格式字符串用到的API:1.先new一个ObjectMapper对象ObjectMapperom=newObjectMapper();StringjsonStr=om.writeValueAsString(传入java对象);System.ou..

    2022年9月15日
    2
  • Mutex的lock(), tryLock()区别[通俗易懂]

    Mutex的lock(), tryLock()区别[通俗易懂]lock函数和tryLock函数都是用于锁定对象,但他们之间有一定的区别:lock函数是阻塞的,因为它调用WaitForSingleObject函数时传递的第二个参数是INFINITE,表示无限等待下去,所以是阻塞的。tryLock函数时非阻塞的,调用后立即返回。因为它调用WaitForSingleObject函数时传递的第二个参数是0,表示不等待,立即返回。调用lock或者tryLoc

    2022年10月16日
    1
  • 文件和文件流

    文件和文件流文件和文件流1.File类Java.io.File类可以获取文件以及文件夹的一些基本的属性常用的方法文件名称,路径,大小,判断是否存在,删除,创建//创建一个文件对象(可以是文件,可以是文件夹) Filefile=newFile(“e:/java_text.txt”); //基本属性 booleancanWriter=file.canWrite(); …

    2025年8月5日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号