关于memset的void*参数及char*强制转换的技术疑问
关于memset工作原理与ft_memset实现的疑问解答
首先贴出你实现的ft_memset代码:
void *ft_memset(void *s, int c, size_t n) { size_t i; i = 0; while (i < n) { *((char *)(s + i)) = c; i++; } return (s); }
疑问1:为什么memset接收void*类型的参数,它似乎无法处理int类型,除char外还可用于哪些类型?
- 用
void*做参数是为了通用性:C语言里void*可以指向任意数据类型的内存块,不管你要填充的是char数组、int数组、结构体还是自定义类型的内存区域,都能直接传指针进去,不用做额外类型转换,这是标准库函数通用化的设计思路。 - 所谓“无法处理int类型”是误解:memset的逻辑是逐字节填充,它会把
int c的低8位(等价于unsigned char c的值)复制到目标内存的每个字节里。如果给int数组用memset,比如int arr[5]; memset(arr, 0, sizeof(arr));是完全可行的,因为0的每个字节都是0;但如果用memset(arr, 1, sizeof(arr)),每个int会被填充成0x01010101(假设int是4字节),而不是每个int都等于1,这是初学者容易混淆的点。 - 除了char,还能用于几乎所有类型:比如给结构体清零、初始化float数组为0.0(因为0的字节表示全0)、填充自定义内存缓冲区、甚至给指针数组填NULL(如果NULL的字节表示全0的话)。
疑问2:为什么强制转换为char*能让该实现适配所有场景?
- 核心原因是
char*的步长是1字节:memset的本质是填充连续的n个字节,而void*本身不能做指针算术(编译器不知道它指向的类型占多少字节,s + i如果是void*属于非法操作)。 - 强制转成
char*后,每次i++都会让指针移动1字节,刚好对应memset需要逐个字节修改的逻辑。不管原指针指向的是int、float还是其他类型,转成char*后都能精准遍历每一个目标字节,完成填充操作,这样就适配了所有内存块的场景。
内容的提问来源于stack exchange,提问作者xTurtho
相关产品推荐
相关产品推荐

