memmove正在复制0个字节,但引用超出界限是否安全
Is memmove copying 0 bytes but referencing out of bounds safe
我在网上读到,如果要复制的字节数为0,则memmove
预计不会执行任何操作。然而,我想知道的是,在这种情况下,是否预期不会读取源指针和目标指针
下面是我的一些代码的简化版本,我感兴趣的部分是shiftLeft
:
#include <array>
#include <cstring>
#include <iostream>
class Foo final {
unsigned just = 0;
unsigned some = 0;
unsigned primitives = 0;
};
template <unsigned Len>
class Bar final {
unsigned depth = 0;
std::array<Foo, Len> arr;
public:
Bar() = default;
// Just an example
void addFoo() {
arr[depth] = Foo();
depth++;
}
void shiftLeft(unsigned index) {
// This is what my question focuses on
// If depth is 10 and index is 9 then index + 1 is out of bounds
// However depth - index - 1 would be 0 then
std::memmove(
&arr[index],
&arr[index + 1],
(depth - index - 1) * sizeof(Foo)
);
depth--;
}
};
int main() {
Bar<10> bar;
for (unsigned i = 0; i < 10; ++i)
bar.addFoo();
bar.shiftLeft(9);
return 0;
}
当Len
是10
,depth
是10
,并且index
是9
时,则index + 1
将读出越界。然而,在这种情况下,depth - index - 1
也是0
,这应该意味着memmove
将不执行任何动作。这个代码安全吗?
memmove
函数将复制n
字节。如果n
为零,它将不起任何作用。
唯一可能的问题是,其中index
已经达到数组元素的最大值:
&arr[index + 1]
但是,您可以引用数组中的数组元素(指针指向它们(,也可以引用数组末尾以外的假设元素
您可能不会取消引用后者,但您在这里没有这样做。换句话说,虽然arr[index + 1]
本身会尝试取消引用,因此是无效的,但评估其地址是可以的。
这在C++20 [expr.add]
:中有所涉及,尽管是切向的
将具有整型的表达式添加到指针或从指针中减去时,结果具有指针操作数的类型。如果表达式
P
指向具有n
元素的阵列对象x
的元素x[i]
,则表达式P + J
和J + P
(其中J
具有值j
(指向(可能假设的(元素x[i + j] if 0 ≤ i + j ≤ n
;否则,行为是未定义的。
注意if 0 ≤ i + j ≤ n
子句,特别是最后一个≤
。对于数组int x[10]
,表达式&(x[10])
是有效的。
[basic.compound]
(我的重点(:也涵盖了这一点
指针类型的值是指向或超过对象末尾的指针,该值分别表示对象占用的内存中第一个字节的地址,或对象占用的存储结束后内存中的第一个字节。
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 何时在引用或唯一指针上使用移动语义
- 如何在c++中使用引用实现类似python的行为
- 编译C++时未定义的引用
- Ctypes wstring通过引用传递
- c++r值引用应用于函数指针
- 理解c++中的引用
- C++取消引用指针.为什么会发生变化
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 强制转换为引用类型
- 引用一个已擦除类型(void*)的指针
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 具有默认值的引用获取函数
- 如何使用基类指针引用派生类成员
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 如何引用基类的派生类?