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的話,應該也是初始化正常的(這里就不進行實驗啦)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM