问题背景: C语言在类型转换方面一直很灵活,以便更方便地处理低级内存和各种平台。然而,它的简洁性和强大功能容易导致由不当类型转换引起的漏洞和缺陷,特别是在处理指针和位运算时。
问题:
解决方案:
代码示例:
#include <stdio.h> void print_double_as_int(double d) { int i = (int)d; printf("Value: %d\n", i); } void *ptr = malloc(16); int *ip = (int*)ptr; // 访问原始内存:如果ptr确实指向int,则可以接受
关键特点:
1. 何时可以将void*转换为结构体指针,这总是安全吗?
这种转换是安全的,如果地址确实指向该结构的实例,否则行为是未定义的(undefined behavior)。
2. 如果将一个长度的结构体指针转换为一个字段更少或更多的结构体指针,会发生什么?
访问“新”结构的字段将导致在原始结构的边界之外读取/写入,可能导致数据损坏。
代码示例:
typedef struct {int a;} S1; typedef struct {int a; int b;} S2; S1 s; S2 *ps2 = (S2*)&s; // ps2->b — 访问“垃圾”
3. 可以安全地将int指针转换为char指针以访问该数字的字节吗?
这是处理内存的一种典型方法——按字节访问是可以的,但需要小心,因为可能会出现对齐问题,字节顺序取决于架构(大端/小端)。
初级程序员为了优化访问时间处理网络数据包,将指针从原始数组转换为不同类型字段的数据结构指针。
优点:
缺点:
经过修改后,每个数据包的字节通过memcpy手动提取。
优点:
缺点: