memset的问题

#include <stdio.h>
#include <string.h>

int main()
{


    int b = 0;

    memset(&b, 0x0102, 3);

    printf("b=0x%x\n", b);

    return 0;
}


输出为b=0x20202
看了memset的实现,原来是将0x0102的最低位(0x02)来赋值的
glibc库的memset的实现为

 

void *
memset (dstpp, c, len)
     void *dstpp;
     int c;
     size_t len;
{
  long int dstp = (long int) dstpp;

  if (len >= 8)
    {
      size_t xlen;
      op_t cccc;

      cccc = (unsigned char) c;
      cccc |= cccc << 8;
      cccc |= cccc << 16;
      if (OPSIZ > 4)
	/* Do the shift in two steps to avoid warning if long has 32 bits.  */
	cccc |= (cccc << 16) << 16;

      /* There are at least some bytes to set.
	 No need to test for LEN == 0 in this alignment loop.  */
      while (dstp % OPSIZ != 0)
	{
	  ((byte *) dstp)[0] = c;
	  dstp += 1;
	  len -= 1;
	}

      /* Write 8 `op_t' per iteration until less than 8 `op_t' remain.  */
      xlen = len / (OPSIZ * 8);
      while (xlen > 0)
	{
	  ((op_t *) dstp)[0] = cccc;
	  ((op_t *) dstp)[1] = cccc;
	  ((op_t *) dstp)[2] = cccc;
	  ((op_t *) dstp)[3] = cccc;
	  ((op_t *) dstp)[4] = cccc;
	  ((op_t *) dstp)[5] = cccc;
	  ((op_t *) dstp)[6] = cccc;
	  ((op_t *) dstp)[7] = cccc;
	  dstp += 8 * OPSIZ;
	  xlen -= 1;
	}
      len %= OPSIZ * 8;

      /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain.  */
      xlen = len / OPSIZ;
      while (xlen > 0)
	{
	  ((op_t *) dstp)[0] = cccc;
	  dstp += OPSIZ;
	  xlen -= 1;
	}
      len %= OPSIZ;
    }

  /* Write the last few bytes.  */
  while (len > 0)
    {
      ((byte *) dstp)[0] = c;
      dstp += 1;
      len -= 1;
    }

  return dstpp;


 

### 关于 `memset` 函数的使用 #### 函数定义 在 C 和 C++ 中,`memset` 是一个标准库函数,用于将一块连续的内存区域填充为指定的值。它的声明位于头文件 `<cstring>` 或者 `<string.h>` 中。 ```cpp #include <cstring> // 或 <string.h> void* memset(void* dest, int value, size_t count); ``` - **参数说明** - `dest`: 要操作的目标内存地址。 - `value`: 填充到目标内存中的值,该值会被转换成无符号字符(unsigned char)后再存储。 - `count`: 需要填充的字节数量。 - **返回值**: 返回指向已修改内存块的第一个字节的指针[^1]。 --- #### 使用场景与示例 ##### 初始化数组 可以利用 `memset` 将整个数组的内容设置为特定值,最常见的是将其置零。 ```cpp #include <iostream> #include <cstring> int main() { int a[5] = {1, 2, 3, 4, 5}; // 将数组 a 的每个字节替换为 0 memset(a, 0, sizeof(a)); for (int i = 0; i < 5; i++) { std::cout << a[i] << " "; } } // 输出: 0 0 0 0 0 ``` 此代码片段展示了如何通过调用 `memset` 来清除整数数组的所有元素至零状态[^2]。 --- ##### 结构体初始化 对于复杂的数据结构如自定义结构体,也可以借助 `memset` 实现快速初始化。 ```cpp typedef struct { int a; float b; double c; } TEST; int main() { TEST test; // 设置结构体内存全为 0 memset(&test, 0, sizeof(TEST)); std::cout << test.a << "\n"; // 输出: 0 std::cout << test.b << "\n"; // 输出: 0.000000 std::cout << test.c << "\n"; // 输出: 0.000000 return 0; } ``` 需要注意的一点是,如果结构体成员包含指针或其他动态分配的对象,则简单地应用 `memset` 可能不会达到预期效果,甚至可能引发未定义行为[^4]。 --- ##### 动态内存初始化 当涉及堆上的数据管理时,同样适用 `memset` 方法来完成必要的预处理步骤。 ```cpp #include <cstdlib> #include <cstdio> int main() { int* temp = (int*)malloc(5 * sizeof(int)); // 开辟五个 int 类型的空间 if (!temp) return -1; // 检查 malloc 是否成功 // 利用 memset 把这些空间内的所有位都设为 0 memset(temp, 0, 5 * sizeof(int)); for (int i = 0; i < 5; ++i){ printf("%d ", temp[i]); } free(temp); // 记得释放资源 return 0; } // 输出结果:0 0 0 0 0 ``` 这里强调一点,尽管可以通过 `memset` 给任意大小的缓冲区赋固定数值,但由于其逐字节操作特性,在某些情况下可能会遇到意想不到的结果,比如尝试设定负数或者浮点类型的特殊值时应格外小心[^4]。 --- ### 注意事项 虽然 `memset` 提供了一种简便的方式来进行批量赋值,但在实际开发过程中需谨慎对待以下几个方面: 1. 数据类型匹配问题; 2. 不适合直接应用于含有非平凡构造器/析构器的类实例; 3. 当前仅限于基本数据类型的单值覆盖,无法满足更复杂的逻辑需求。 以上就是有关 `memset` 函数的一些基础介绍及其典型应用场景[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值