如果不使用数组外部的数据,访问数据是否不正确?
Is accessing data outside an array incorrect if you don't use it?
在我正在编写的算法中,我可以有以下(当然简化了)
int a[3] = {1,2,3};
int b = a[3];
当用于填充b
的索引溢出时,I 从不使用b的值,代码是否仍然不正确?我是否必须进行明确的边界检查? 无论您是否使用b
,此代码都具有未定义行为。为什么?因为根据定义,a[3]
等于*(a+3)
。这里引用了标准中的一段话,证明*(a+3)
本身是未定义的,无论该值是存储、使用还是保留。
当一个表达式具有类型被加到或减去指针,结果的类型为指针操作数。如果指针操作数指向an的一个元素数组对象,且数组较大够了,结果指向一个元素与原始元素的偏移量的不同之处结果和的下标原始数组元素等于积分表达式。换句话说,如果表达式P指向第i个数组对象的元素表达式(P)+N(等价地,N+(P)和(P)-N(其中N是值n)分别指向的I +n和I - n个元素数组对象,前提是它们存在。此外,如果表达式P点到数组的最后一个元素对象,表达式(P)+1分数组的最后一个元素后面对象,如果表达式Q点数组的最后一个元素之后的一个对象,表达式(Q)-1指向数组对象的最后一个元素。如果指针操作数和结果指向相同的元素数组对象,或倒数一个数组对象的评价不得产生不良后果溢出;否则,行为为定义。
仍然不正确,仍然未定义的行为。做边界检查
int b = *(a + 3); // dereferencing beyond the array bound.
读取a[3]
已经导致未定义行为。由于未定义行为从未在本地受到限制,这已经可能导致您的硬盘驱动器被格式化,或者您的计算机出现一个巨大的食肉僵尸。
在现实中,它通常只是工作。但是很容易出现这样的情况,即数组的末尾标志着映射内存区域的结束,因此访问超出该区域的一个元素将导致分段错误。这当然不是堆栈上的int
数组的情况,也不是大多数堆实现的情况,但你不应该依赖它。
(获取&a[3]
的地址是否也是未定义行为存在很大争议)
这仍然是不正确的,因为您访问了越界内存位置以获取值a[3]
并将其存储在变量b
中。
您从未使用b
的事实可能意味着编译器优化了那行代码,因此您可能从未看到该行存在的任何不利影响。
但是,编译器不需要这样做,代码本身仍然有未定义的行为。
可以。
你是使用的值,通过复制到b
。
更具体地说,解引用(a+3)
是不允许的,因为表达式(a+3)
不是一个有效的指针…表达式 a[3]
相当于*(a+3)
(其中a
已经衰变为指针表达式)。
是的,阅读不存在的a[3]
是错误的。
使用b
也是错误的,但是已经太晚了。
- 用于访问容器<T>数据成员的正确 API
- 使用指针访问数组中的对象数据成员
- 友元函数无法访问私有数据成员 (c++)
- OpenCV C++ 3 维垫数据访问错误值
- 用于随机数据访问的最有效文件类型
- 用于多维数据访问的重载 () 运算符
- MEX C++原始数据访问
- C++数据访问基准
- 随机 mmaped 内存访问比堆数据访问慢 16%
- 共享内存多线程和数据访问
- 如何使用常见的C 业务逻辑和数据访问层构建跨平台移动应用程序
- 链表数据访问
- OpenMP线程、数据访问延迟和STL数据容器
- C++ 矢量数据访问
- 我很难在C++类中实现我想要的数据访问
- 概括模型中的数据访问.避免宏观的方法
- 矢量化/优化循环,用于宽寄存器(特别是Xeon Phi)的未对齐数据访问
- 松类耦合和数据访问
- 在Linux上锁定对单个进程内数据访问的最快方法
- 如何使用数据访问对象进行序列化和关系数据库数据访问