memset和memcpy函数

memset和memcpy是两个常见函数,用于处理内存块的操作。

memset函数

memset函数用于将一块内存区域的内容设置为特定的值

函数原型为:void* memset(void* ptr, int value, size_t num);

其中:

  • ptr:指向要填充的内存块的指针。
  • value:要设置的值。
  • num:要设置的字节数。

函数功能描述:该函数将ptr指向的内存块中前num个字节设置为value。

注意事项:

  • memset 并不对指针 ptr 指向的内存区域做边界检查,因此使用时需要确保 ptr 指向的内存区域足够大,避免发生越界访问。
  • memset 的第二个参数value通常是一个 int 类型的数值,但实际上函数实现中只使用了该数值的低8位。这意味着如果传入0~255之外的其他数值可能会产生未定义的行为。
  • num 参数通常是通过sizeof 等计算函数得到的。

常见用法就是将内存块快速置0,例如:

char auc_buff[64] = { 0 };
char str1[32] = { 0 };
char str2[32] = { 0 };

// set_static_string函数为自定义函数,功能类似memcpy,将auc_buff传入str
get_value(SYS_CONFIG, "info.id", auc_buff, sizeof(auc_buff))    //获取值
set_static_string(auc_buff, str1, sizeof(str1));
memset(auc_buff, 0, sizeof(auc_buff));    //将缓冲池置0,为下次读写做准备
get_value(SYS_CONFIG, "info.sid", auc_buff, sizeof(auc_buff))
set_static_string(auc_buff, str2, sizeof(str2));
memset(auc_buff, 0, sizeof(auc_buff));
......

错误示范:

        因为函数实现中第二个参数 value 只使用了低8位。如果使用 int 类型的变量进行赋值,使用除 -1 0 以外的其他整数会出现问题。例如使用 1 进行赋值,1 的二进制表示为 0000 0001,使用 memset(num, 1, sizeof(num)) 进行赋值时memset函数初始化每个字节为:0000 0001, 0000 0001, 0000 0001...此时前4字节组成 int 整数时为:16843009 而非1。

        造成这种现象的原因主要是 memset 函数在做初始化的时候是以 字节(byte) 为单位的,也就是 8 位二进制数。由于 bool char 类型的变量都是 1 字节,所以使用 bool 和 char 类型进行初始化的时候不会出现问题,但使用 int 类型进行初始化一定要注意这个问题。当然,使用 int 类型进行初始化一般用作快速置0,使用 -1 和 0 时并不会出现问题。

memcpy函数

memcpy函数用于将源内存区域内容复制到目标内存区域,不可以处理重叠的内存区域。

函数原型为:void* memcpy(void* dest, const void* src, size_t num);

其中:

  • dest:指向目标内存区域的指针。
  • src:指向源内存区域的指针。
  • num:复制的字节数

函数功能描述:该函数将 src 指向内存区域的 num 字节复制给 dest 指向的内存区域。

注意事项:

  • 确保目标内存区域足够大,注意 num 的大小设置,一般用 sizeof(dest) 进行表示,避免出现dest 内存溢出的情况。
  • memcpy 函数可以处理任意类型的内存块,在涉及指针类型转换时,要确保转换的正确性,避免发生未定义行为。

内存溢出举例:

char info_config[100];
char info_svn[50];

//如果使用sizeof(info_config)会造成info_svn的内存溢出
memcpy(info_svn, info_config, sizeof(info_svn));    

如果需要处理内存重叠的情况,可以考虑使用 memove 函数。

memset 与 memcpy 的区别

  • memset 只对一个内存区域有操作,用于设置内存块的值;memcpy 有两个内存区域参与,用于复制内存块的值。
  • memset 将整个内存块设置成指定值;memcpy 只会对内存块中指定大小的区域产生影响。

值得注意的是两个函数都是基于字节进行操作,在使用过程中要谨慎处理内存边界和类型转换问题,以避免出现意外行为造成不可预知的错误。

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值