读取空白*指向字符作为整数的安全性
How safe is reading a void * pointing to a char as an int?
读取一个空白*指向一个字符作为整数有多安全?
示例:在 8 位字符访问比 32 位整数慢得多的系统中测试 char 的第一个位。
char c = 'B'; // a char here to illustrate the potentially dangerous case, but the
// point is this could be a char, could be an int... I am just
// interested in the first bit
void *v = &c;
int i = *(int *)v;
if (i & 0x01)
{
printf("yep");
}
似乎有效,但是如果我的字符 (c) 正好位于分配给此进程的有效内存的边缘,它会读取无效内存吗?还是系统足够聪明,可以在前 8 位后停止复制?
谢谢
在所有情况下,它都是未定义的行为。
在大多数实际系统中,它将从c
和相邻内存中正常读取,如果c
接近内存页的末尾并且相邻页被标记为不可读,则失败(访问冲突又称为分段错误)。
在数量较少但仍然不平凡的系统中,您可能会遇到对齐错误和/或读取与c
重叠但在开始以外的某个位置c
的 32 位值。
但是,如果编译器发现您这样做,它将获得标准许可,以非常破碎的方式"优化"所有代码。
如果您害怕 8 位访问速度较慢的系统,请使用 int_fast8_t
而不是 char
。 这允许您的构建环境选择更好的变量大小。
不,这不安全。
而且您的用例完全是人为的,因为我从未听说过读取 32 位值比读取 8 位值更快的系统。如果有的话,有时是相反的。
(即使你找到了这样的系统,也要把这样的"优化"留给编译器,它会做得更好。
系统不够聪明,你的程序容易出现内存访问违规
这只是未定义的行为。
另一方面,我可以想象这将起作用的情况。请注意,在声明 c
之后,您声明v
。由于c
在堆栈上,通过将其地址转换为void*
然后取消引用它,您可能会得到int
,它将由 c
的 1 个字节和v
的 3 个字节组成。但这只是众多可能的实现之一。
int 变量将加载 3 个字节加上您要加载的字节。此外,您的 int 转换也可能导致错位。而且,这种强制转换在平台之间不可移植,根据您在 if 中屏蔽的方式,其恩迪度不同。这是一种糟糕的方法,请重新构建您的系统以避免当前情况。
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 检查输入是否不是整数或数字
- C++使用整数的压缩数组初始化对象
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何只允许用户输入正整数
- 如何在c++中从文本文件中逐行读取整数
- C++:如何循环通过向量中的整数元素
- 类与私有变量的其他类之间的线程安全性
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 使用固定整数类型的安全性
- 将整数解释为字节数组的安全性
- 在 void 指针中存储整数的往返安全性
- 读取空白*指向字符作为整数的安全性
- 安全地加整数,并证明其安全性