static_cast<int*>(ptr)[0]
强制转换ptr
并int*
读取第一个元素。由于原始数组只有 2 个字节,因此您正在读取它之外的内容(因为您正在读取 4-byte int
)并调用未定义的行为,除非int
您的系统上是 2-byte 类型。您还违反了严格的别名规则,因为您使用不同的指针类型访问了一个类型,该类型也调用了 UB。此外,如果 bool 数组未正确对齐,您将获得 UB 。在 x86 上它不会导致任何问题,因为 x86 默认情况下允许未对齐访问,但在大多数其他架构上您会遇到段错误
static_cast<int>(test[0])
OTOH 将test[0]
(即 a bool
)int
转换为完全有效的值转换。
更新:
类型int*
指对象为 4 字节长的指针,而bool*
指对象为 2 字节长的指针
不。当取消引用变量var
时,将从该地址开始的内存中读取一定长度的内存sizeof(var)
并将其视为该变量的值。所以*bool_ptr
将读取 1 个字节并*int_ptr
从内存中读取 4 个字节(如果bool
和int
分别是 1 和 4 字节类型)
在您的情况下,bool
数组包含 2 个字节,因此当从 读取 4 个字节时,将读取数组内部的 2 个字节和static_cast<int*>(ptr)
数组外部的 2 个字节。如果您声明(或更多元素),您将看到取消引用成功完成,因为它读取了属于您的所有 4 个布尔值,但您仍然遇到不对齐问题bool test[4] = {};
int*
现在尝试将布尔值更改为非零值并查看
bool test[4] = { true, false, true, false };
您很快就会意识到,将指针转换为不同的指针类型并不是简单地读取旧类型并转换为新类型,就像简单的值转换(即转换),而是不同的“内存处理”。这本质上只是一个reinterpret_cast
您可以阅读以了解有关此问题的更多信息
我不明白你在说什么char*
。您是说从任何类型转换char*
为有效?
从任何其他指针类型转换char*
为有效。阅读上面关于严格别名规则的问题:
您可以使用char*
别名而不是系统的单词。规则允许char*
(包括signed char
和unsigned char
)例外。它总是假定char*
别名其他类型。
它用于memcpy
将表示类型的字节复制到不同目的地的地方
bool test[4] = { true, true, true, true };
int v;
memcpy((char*)&test, (char*)&v, sizeof v);
技术上mempcy
接收void*
,演员char*
表只是用来演示的
也可以看看