编程之美-内存函数

简介: memcpy内存拷贝• 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。• 这个函数在遇到 ‘\0’ 的时候并不会停下来。• 如果source和destination有任何的重叠,复制的结果都是未定义的。

文章目录


内存函数

memcpy内存拷贝

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 ‘\0’ 的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。


原格式

image.png

分析

**字面上意思只要是内存里面的东西就都可以进行拷贝,所以就打破了字符串拷贝的魔咒,什么类型都可以进行拷贝,那就不需要想来,肯定回和万能类型(通用类型指针-无类型指针)void*有关,因为当时做qsort还是印象深刻的

/*num是几个字节的意思*/
void* my_memcpy(void* dest, const void* src, size_t num)
{
  assert(dest && src);
  void* ret = dest;
  while (num--)
  {
    //和void*连用char*,分成最小然后一个一个传
    *(char*)dest = *(char*)src;
    ((char*)dest)++;//void*无类型不好直接加加,就强转char*再加加
    ((char*)src)++;
  } 
  return ret;
}


内存拷贝的问题

1.内存相关连的话,就会拷贝错误

image.png

那你怎么解决内存相关连还不会有上面的错误,正面赋值交集的内存空间会被操作两次,就会改变原来的值,那我们怎么做呢,如果从后面来呢,前面操作两次会把后面的变了,那就先把后面的拿走赋值,不就间接的改变了原来会变的情况了吗,所以这样上面的代码就得修改了,这是朝后面拷贝的情况,如果提目是朝前面拷贝的话,是不是从后面来就有问题了,反而从前面来会比较完美,所以我们得两种情况都得考虑到


所以为了解决重叠拷贝的问题就有了memmove这个函数

2.内存不够了还要朝里面拷贝直接程序挂了

image.png


memmove内存重叠拷贝

用来处理内存重叠的情况

C语言规定

memcpy 只要处理内存不重叠的拷贝就可以

memmove 处理重叠内存拷贝

我们重写memcpy的代码是满足C语言要求的,在vs这个编译器中memcpy实际上是超额完成任务了,他的效果已经和memmove效果一样了

image.png

你会发现他们跑出来的效果 是一样的,所以上面那个测试我就是用我自己的代码测试的(已经达到C语言的标准了)

我们再精细点就是memmove的内容了


原格式

image.png

分析

image.png

image.png

image.png

image.png

/*num是几个字节的意思*/
void* my_memmove(void* dest,const void* src, size_t num)//memmove和memcpy的参数是一样的
{
  assert(dest && src);
  void* ret = dest;
  if (dest < src)
  {
    while (num--)
    {
      //sre内存从前向后拷贝
      //和void*连用char*,分成最小然后一个一个传
      *(char*)dest = *(char*)src;
      ((char*)dest)++;//void*无类型不好直接加加,就强转char*再加加
      ((char*)src)++;
    }
  }
  else
  {
    while (num--)
    {
      //sre内存从后向前拷贝
      //和void*连用char*,分成最小然后一个一个传
      *((char*)dest+num) = *((char*)src+num);
      //((char*)dest)++;//void*无类型不好直接加加,就强转char*再加加
      //((char*)src)++;
    }
  } 
  return ret;
}

image.png


memset内存设置

将缓冲区设置为指定的字符。

原格式

image.png

分析

image.png

image.png

//变量c代表的是字符的ASCII码
void* my_memset(void* dest, int c, size_t count)
{ 
  const unsigned char uc = c;    //把c转成字符,且不可变用const  
  void* ret = dest;
   int i = 0;
   for (i = 0; i < count; i++)
   {
    *(char*)dest = uc;
    ((char*)dest)++;
   }
   return ret;
}


memcmp内存比较

和strcmp相似,只不过一个是比较字符串,一个比较内存,由于不知道什么类型,所以后面有字节个数限制,准确的说应该和strncmp相似,因为后面都有一个个数的参数

原格式

image.png

分析

基本和字符串比较一样,就是变成了内存比较罢了

image.png

image.png

//buf1内存里的内容比buf2内存里的内容大就>0,反之<0
int my_memcmp(const void* buf1, const void* buf2, size_t count)
{
  assert(buf1 && buf2);
  while (--count && *(char*)buf1 == *(char*)buf2)//这个先减减就是细节
  {
    ((char*)buf1)++;
    ((char*)buf2)++;
  }
  if (*(char*)buf1 - *(char*)buf2 > 0)
    return 1;
  if (*(char*)buf1 - *(char*)buf2 < 0)
    return -1;
  return 0;
}

给你count不要乱超,因为他操作的是内存,没有字符串补\0的功能


目录
相关文章
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
34 3
|
1月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
174 1
|
1月前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
27天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
22 0
|
1月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
40 0
|
1月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
66 0
|
1月前
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
70 0
|
1月前
|
编译器 C语言 C++
【C语言】精妙运用内存函数:深入底层逻辑的探索
【C语言】精妙运用内存函数:深入底层逻辑的探索