使用calloc分配内存后memset赋值非0值异常的解决方法
问题:memset赋值非0值出现异常的原因及解决方法
我通过calloc分配了内存,希望使用memset为该内存赋值。当赋值为0时可以成功,但赋值非0值时会出现异常值,请问如何通过memset成功完成这类赋值?
相关代码
#include <stdio.h> #include <stdlib.h> #include <cstring> int main() { int size = 5 ; int* c = (int*)calloc(size,sizeof(int)); memset(c,0,size*sizeof(int)); // 输入1或其他值时无法正常工作 for (int i=0; i<size;i++){ printf("values %d\n", c[i]); } free(c); }
程序输出
赋值为0时的输出
values 0 values 0 values 0 values 0 values 0
将memset参数改为1后的输出
values 16843009 values 16843009 values 16843009 values 16843009 values 16843009
原因及解决方法
问题根源
memset是按单个字节填充的函数,它会把你传入的第二个参数(比如1)复制到目标内存的每一个字节中。而在多数系统里,int类型占4个字节(32位),当你用memset(c, 1, ...)时,每个int的4个字节都会被设为0x01,组合起来就是十六进制的0x01010101,转换成十进制就是16843009——这就是你看到的“异常值”。
而赋值0时,每个字节都是0,组合后的int值自然也是0,所以看起来正常。
解决办法
memset只能满足每个字节都相同的整数赋值需求(比如想给每个int赋值0x01010101,用memset(c,1,...)是正确的)。如果是想给每个int赋值任意整数(比如十进制1),memset做不到,推荐以下两种方法:
- 循环逐个赋值(兼容性最好,通用所有场景):
// 替换原来的memset行 for (int i = 0; i < size; i++) { c[i] = 1; // 这里可以换成你需要的任意int值 }
- 利用编译器扩展函数(可选):
如果使用GCC或Clang编译器,可以用memset_pattern4函数直接填充4字节的整数:
int fill_val = 1; memset_pattern4(c, &fill_val, size * sizeof(int));
不过这种方法依赖编译器特性,跨平台兼容性不如循环。
另外补充:你用calloc分配的内存本身已经被初始化为0,所以代码里的memset(c,0,...)是多余的,可以直接删除。
内容的提问来源于stack exchange,提问作者Paroz
相关产品推荐
相关产品推荐

