memset()函数的使用注意

最近,同事在负责一个项目的时候遇到一个问题:数组初始化后值异常,后来找出是使用memset函数的锅,这里我也来跟着学习下。。

C语言中memset源码如下:

void *memset(void *s, int c, size_t count)
{
    char *xs = s;

    while (count--)
        *xs++ = c;
    return s;
}

我们可以发现,在memset()函数中,会将(void *)类型转换成(char *)类型,这样会有什么影响呢?

1、试验一

#include <stdio.h>
#include <string.h>
 
int main(void)
{
     int i=0,j=0;
     int array_1[16];
     char array_2[16];
 
     memset(array_1, 0, 16);
     memset(array_2, 0, 16);
 
     printf("[array_1]:");
     for(i; i<16; i++)
     {
         printf("%d  ",array_1[i]);
     }
     printf("\n");
 
     printf("[array_2]:");
     for(j; j<16; j++)
     {
         printf("%d  ",array_2[j]);
     }
     printf("\n");
 
     return 0;
}

这里分别设置两个类型的数组,一个int型,一个char型,那么输出结果如下:

[array_1]:0 0 0 0 1835627636 1600061541 1869833334 1952802655 1 0 4196205 0 0 0 0 0
[array_2]:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

可以发现,这时候int型的数组初始化是异常的。若细心一点可以发现,int型数组的前4个成员都是为0的(16个字节),这个长度刚好是array_2的长度。那这是不是由于memset是以char为单位进行置0,所以只初始化了int型数组的前四个成员呢?

2、试验二:

memset(array_1, 0, 64);

那么输出结果如下:

[array_1]:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[array_2]:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

可以发现,int型数组初始化完成了。那么是不是指针转换是数据丢失呢?

3、实验三:

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

int main(void)
{
    int *addr_1 = (int *)0x12345678;

    char *addr_2 = (void *)addr_1;

    printf("addr_1 : %p\n",addr_1);
    printf("addr_2 : %p\n",addr_2);

    return 0;
}

那么输出结果如下:

addr_1 : 0x12345678
addr_2 : 0x12345678

也是就说,不同类型的指针的指针长度是一样的,但是,指针偏移的时候会根据所声明的类型来进行偏移。如同样是prt++,int *表示偏移是4个字节,char *则表示偏移是1个字节

既然这样的话,那么如果结构体里面成员类型不同的话,那么结构体的初始化也会有影响吗?

4、实验四:

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

typedef struct _s_param
{
  int a;
  int b;
  char c;
}S_PARAM;

typedef struct _s_var
{
  char a;
  char b;
  int c;
}S_VAR;

int main(void)
{
  S_PARAM param;
  S_VAR var;

  memset(&param, 0, sizeof(S_PARAM));
  memset(&var, 0, sizeof(S_VAR));

  printf("[param(%ld)] a=%d, b=%d, c=%d\n",sizeof(S_PARAM), param.a,param.b,param.c);
  printf("[var(%ld)] a=%d, b=%d, c=%d\n",sizeof(S_VAR), var.a,var.b,var.c);
}

那么输出结果如下:

[param(12)] a=0, b=0, c=0
[var(8)] a=0, b=0, c=0

可以发现结构体的初始化是正常的,这是因为输入的长度是结构体的长度,那这样的话,那前面的数组初始化用sizeof的话,应该也是初始化正常的(这里就不进行实验啦)

 

posted @ 2019-07-21 14:25  Recca  阅读(1532)  评论(0编辑  收藏  举报