指针与不同大小整数强制转换触发segmentation fault问题求解
问题分析与解决方法
错误原因
- 架构类型宽度不匹配:当前主流设备均为64位架构,内存指针(地址)长度为8字节,但
unsigned int在通用编译环境中仅占4字节。将数组地址强制转换为unsigned int时会截断高位地址,得到的非法地址后续解引用时就会触发段错误。 - 类型使用不符合约定:你书中的结论成立前提是
unsigned int宽度等于指针宽度,也就是32位运行环境,这已经不是当前设备的默认环境。C标准本身也没有约定unsigned int必须能够容纳指针值。 - 输出格式参数不匹配:
printf的%p格式符要求传入void*类型参数,直接传入unsigned int属于未定义行为,也可能触发运行异常。
正确可运行实现
你可以使用C标准定义的uintptr_t类型复现书中的逻辑,该类型定义在<stdint.h>头文件中,专门用于存储指针值,保证宽度和当前系统的指针宽度一致。修改后代码如下:
#include <stdio.h> #include <stdint.h> int main() { int i; char char_array[5] = {'a', 'b', 'c', 'd', 'e'}; int int_array[5] = {1,2,3,4,5}; uintptr_t hacky_nonpointer; hacky_nonpointer = (uintptr_t) char_array; for(i=0;i<5;i++) { printf("[hacky_nonpointer] 指向 %p, 存储的字符为 '%c'\n", (void*)hacky_nonpointer, *((char *) hacky_nonpointer)); hacky_nonpointer = hacky_nonpointer + sizeof(char); } hacky_nonpointer = (uintptr_t) int_array; for(i=0;i<5;i++) { printf("[hacky_nonpointer] 指向 %p, 存储的整数为 %d\n", (void*)hacky_nonpointer, *((int *) hacky_nonpointer)); hacky_nonpointer = hacky_nonpointer + sizeof(int); } return 0; }
如果你需要验证原书的unsigned int版本,可以在编译时指定32位编译参数,例如gcc下使用gcc -m32 你的源文件名.c,编译得到的32位程序运行就不会报错,符合原书的演示逻辑。
内容的提问来源于stack exchange,提问作者rctfx
相关产品推荐
相关产品推荐

