c++ - 是否将其值溢出单个字符的 int 地址转换为指向 char UB 的指针?
问题描述
你好我有这个例子:
int main(){
int x = 300;
char* p = (char*)&x;
printf("%s\n", p);
printf("%d\n", *p);
}
输出:
,
44
只要有一个溢出 a 的正值,它就是将地址
x
转换为未定义行为吗?char*
x
signed char
为什么我得到这个输出?
,
和44
?我试图理解所以我认为300 % 256 = 44
被转换并分配给p
所以它的字符 ASCII 值,
在我的实现中。
你怎么看和推荐?
解决方案
这里没有UB。通常,这样做会违反严格的别名(导致 UB),但有一个例外允许您使用char
指针来访问任何类型。
300
在内存中表示为 4 个字节:(44 1 0 0
假设sizeof(int) == 4
,这是很常见的,并假设是小端序)。
printf("%s\n", p);
将这 4 个字节解释为 C 字符串。您将通过打印得到相同的结果
const char str[4] = {44, 1, 0, 0}; // Same as `{',', '\1', '\0', '\0'}`
300
理论上,如果 的字节表示不包含空字节,您可以获得 UB ,因为它会导致printf
继续读取内存超出 的范围x
,寻找空终止符。但是没有真正的平台可以做到这一点,所以它应该是安全的。
并*p
访问 的表示形式中的第一个字节x
,即44
.
如果您要在大端平台上尝试此代码,您将0
分别得到一个空字符串和 a,因为 的字节表示300
为0 0 1 44
.
x
有一个溢出的正值signed char
这不是问题。
推荐阅读
- ios - How to show time day difference compared to current date?
- biztalk - Unable to cast object of type ‘Microsoft.BizTalk.Administration.EdiExt.ComboItem’ to type ‘System.String’ error in BizTalk Server
- linux - Vulkan memoryHeaps 及其 memoryTypes
- angular - 找不到Angular 6符号链接模块
- python - CalledProcessError 使用 eventlet 越过 try 块
- mysql - 如何在mysql中获取周末天数?
- javascript - 将颜色十六进制混合算法与标准 CMYK 彩色按钮相结合
- spotfire - 如果自定义表达式在公式中包含关键字 with,我该如何乘法?
- firebase - Firebase 托管未连接到自定义域
- google-apps-script - 为 BigQuery 运行 AppScript 脚本时的神秘重复