1. 程式人生 > >memset memcmp memcpy memmove 自己實現

memset memcmp memcpy memmove 自己實現

assert for source null 方式 size_t res 取值 從後往前

memset memcmp memcpy memmove 自己實現

memset

#include <stdio.h>
#include <memory.h>
#include <assert.h>

void* my_memset(void* dest, int c, size_t cnt){
  assert(NULL != dest);
  char *a = (char*)dest;
  while(cnt-- > 0){
    *a++ = c;
  }

  return dest;
}
int main(){
  int a[10];
  for
(int i = 0; i < sizeof(a) / sizeof(int); ++i){ printf("%d ", *(a+i)); } printf("\n"); my_memset(a,0,sizeof(a)); for(int i = 0; i < sizeof(a) / sizeof(int); ++i){ printf("%d ", *(a+i)); } printf("\n"); }

memcmp

#include <stdio.h>
#include <memory.h>
#include <assert.h>
int my_memcmp(const void* s1, const void* s2, size_t cnt){ assert(NULL != s1 && NULL != s2); const char *t1 = s1; const char *t2 = s2; int res = 0; while(cnt-- > 0){ if(*t1 > *t2){ res =1; break; } else if(*t1 < *t2){ res = -1; break; } else
{ t1++; t2++; } } return res; } int main(){ char* s1 = "abcdaaa"; char *s2 = "abcdaa"; int res = my_memcmp(s1,s2,18); if(0 == res) printf("s1 == s2\n"); else if(res > 0) printf("s1 > s2\n"); else printf("s1 < s2\n"); int i1[] = {255,2,3,4,5}; int i2[] = {511,22,23,5}; int res1 = my_memcmp(i1,i2,1); if(0 == res1) printf("i1 == i2\n"); else if(res1 > 0) printf("i1 > i2\n"); else printf("i1 < i2\n"); }

memcpy

如果copy元的首地址 + copy的字節數的結果 >= copy先的首地址的話,就會出現覆蓋,得不到正確的結果。

下面的實現結果太笨了,倒過來復制是最簡單的,請看後面的memmove的實現方式。

include <stdio.h>
#include <memory.h>
#include <assert.h>
#include <malloc.h>

void* my_memcpy(void* dest, const void* src, size_t cnt){

  assert(NULL != dest && NULL != src);

  char *tmp = dest;
  const char *st = src;

  //判斷元的首地址+要copy的字節數是否大於copy先的首地址
  size_t bit = st + cnt - tmp;
  char *tt = NULL;
  char *tm = NULL;
  
  //為了free使用
  char *ta;
  //如果copy的首地址大於元的首地址,並且元的首地址+要copy的字節數是否大於copy先的首地址,覆蓋就會發生,所以要把將被覆蓋的一段內存保存下來,先開辟空間(空間大小是bit),對tt的賦值,在後面的while裏。
  if(tmp > st && bit > 0){
    tt = (char*)malloc(bit);
  }
  //由於tt被用於賦值(初始化),所以tt已經不是首地址了;當copy到被覆蓋的字節的時候,要從首地址拿值,所以從tm中拿值,不從st中拿值;ta一直指向開辟空間的首地址,最後用於釋放這個開辟的空間。
  ta = tm = tt;

  while(cnt-- > 0){
    //tt不為NULL,就是說明了,將要發生覆蓋,所以把要被覆蓋的字節存放到tt中,但要註意不發生覆蓋的字節不需要存放進去,所以加了bit-- > 0的條件
    if(NULL != tt && bit-- > 0){
      *tt++ = *tmp;
    }
    //NULL != tt說明了,是覆蓋patten,並且到了要被覆蓋的字節,所以不從st中取值,從tm中取值。
    if(st >= (char*)dest && NULL != tt){
      *tmp++ = *tm++;
      st++;
   }
   //說明不是覆蓋的patten,無腦復制就可以了。
   else{
     *tmp++ = *st++;
   }

 }
  free(ta);
  return dest;
}

int main(){
  char s1[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
  char *s2 = "xyzdef";

  //char *s3 = memcpy(s1+1,s1,3);                                               
  char *s3 = my_memcpy(s1+1,s1,3);
  printf("s1 = [%s]\n", s1);
  printf("s3 = [%s]\n", s3);


  char s11[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
  char *s22 = "xyzdef";

  char *s33 = memcpy(s11+1,s11,3);
  printf("s11 = [%s]\n", s11);
  printf("s33 = [%s]\n", s33);
  
  int i1[10] = {1,2};
  int i2[10] = {11,22,33,3};
  int i3[10] = {1};
  int *pi3  = i3;
  pi3 = (int*)my_memcpy(i2+2,i2,sizeof(int) * 3);
  for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
    printf("i1[%d] = %d ",i, i2[i]);
  }
  printf("\n");

  for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
    printf("i3[%d] = %d ",i, pi3[i]);
  }
  printf("\n");

}

memmove

#include <stdio.h>
#include <memory.h>
#include <assert.h>

void* my_memmove(void* dest, const void* src, size_t cnt){

  assert(NULL != dest && NULL != src);

  char* tmp = dest;
  const char* st = src;
  //判斷出是覆蓋的patten,所以從後往前覆蓋
  if(tmp > st && st + cnt > tmp){
    while(cnt-- > 0){
      *(tmp + cnt) = *(st + cnt);
    }
  }
  //判斷出不是覆蓋的patten,所以無腦從前往後覆蓋
  else {
    while(cnt-- > 0){
      *tmp++ = *st++;
    }
  }

  return dest;
}

int main(){
  char s1[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
  char *s2 = "xyzdef";

  char *s3 = my_memmove(s1,s1+1,3);
  printf("s1 = [%s]\n", s1);
  printf("s3 = [%s]\n", s3);


  char s11[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
  char *s22 = "xyzdef";

  char *s33 = memmove(s11,s11+1,3);
  printf("s11 = [%s]\n", s11);
  printf("s33 = [%s]\n", s33);


  int i1[10] = {1,2};
  int i2[10] = {11,22,33,3};
  int i3[10] = {1};
  int *pi3  = i3;
  pi3 = (int*)my_memmove(i2+2,i2,sizeof(int) * 3);
  for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
    printf("i1[%d] = %d ",i, i2[i]);
  }
  printf("\n");

  for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
    printf("i3[%d] = %d ",i, pi3[i]);
  }
  printf("\n");
}

memset memcmp memcpy memmove 自己實現