内存函数及其模拟实现

简介: 内存函数及其模拟实现

身体扛不住的时候,意志会带你杀出重围


文章目录


一、memcpy函数


函数介绍


模拟实现


二、memmove函数


函数介绍


模拟实现


三、memset函数


函数介绍


模拟实现


大家好,我是纪宁。这篇文章给大家介绍C语言中常见的内存处理函数。


一、memcpy函数

函数介绍

 memcpy是内存拷贝函数,可以以字节为单位,将一块内存的地址拷贝至另一块内存,因为是以字节为单位进行拷贝,所以任何数据类型都能拷贝,但是memcpy函数的两块地址不能重叠,一旦重叠,可能会出现一些很难预料的结果。




 memcpy函数的第一个参数是目标内存的首地址,第二个参数是要拷贝内存的首地址,第三个参数是需要拷贝的字节数,因为拷贝源的内存空间里的内容不会改变,所以加const修饰,提高函数的安全性。


模拟实现

 在模拟实现memcpy函数的时候,只需要将对应位置的字节交换即可,因为参数传过去的是空指针,所以要先强制类型转化为char* 类型,再进行解引用和赋值,


#include<assert.h>

char* my_memcpy(void* dest,const void* src, size_t num)

{

assert(dest && src);

char* ret = dest;

while (num--)

{

 *(char*)dest = *(char*)src;

 dest = (char*)dest + 1;

 src = (char*)src + 1;

}

return ret;

}

int main()

{

int arr1[10] = { 0,1,2,3,4,5,6,7,8,9 };

int arr2[5] = { 11,12,13,14,15 };

char*st=my_memcpy(arr1, arr2, 20);

int i = 0;

for (i = 0; i < 10; i++)

{

 printf("%d ", arr1[i]);

}

return 0;

}


 在这段代码中,arr1与arr2的内存是单独存在的,他们的内存没有重叠,可是,当将arr1改为arr1+3时,,arr2改为arr1时,预期结果应该是变为{0 1 2 0 1 2 3 4 8 9},可实际在操作的过程中却变成了{0 1 2 0 1 2 0 1 8 9}。这就是他们两块空间内存有重叠的原因。


 为了解决这个问题,我们大多数会使用另一个函数memmove。


二、memmove函数

函数介绍

 memmove函数可以将一块内存的内存移动至另一块,也类似于拷贝函数(memcpy)的功能,但它相较于memcpy函数多了可以处理重叠内存空间的内存拷贝功能。




它的功能与理想中的拷贝内存空间的strcpy函数相同,就不做过多赘述


模拟实现

 通过简单的测试可以得到,当目标内存的空间在源内存空间的后面时,用上面实现strcpy函数的方法从初始位置一个一个拷贝是可以实现目的的,如图




 如果目标内存的空间在源内存空间的前面时,不能达到理想的结果




 所以,对于目标内存的空间在源内存空间前面的情况,我们可以从内存空间的后面往前拷贝、




 总结, 当目标空间位于源空间前面的时候,要从后往前拷贝;当目标空间位于源空间之前的时候,要从前往后拷贝。在函数中用if...else语句来控制即可。


#include<assert.h>

char* my_memmove(void* dest, const void* src, size_t num)

{

assert(dest && src);

char* ret = dest;

if (src > dest)

{

 while (num--)

 {

  *(char*)dest = *(char*)src;

  dest = (char*)dest + 1;

  src = (char*)src + 1;

 }

}

else

 while (num--)

 {

  *((char*)dest + num) = *((char*)src + num);

 }

return ret;

}

int main()

{

int arr1[10] = { 0,1,2,3,4,5,6,7,8,9 };

my_memmove(arr1, arr1 + 3, 20);

int i = 0;

for (i = 0; i < 10; i++)

{

 printf("%d ", arr1[i]);

}

return 0;

}


三、memset函数

函数介绍

 memset函数的作用是以字节为单位改数据。


void* my_memset(void* ptr, int value, int num)

{

int i = 0;

for (i = 0; i < num; i++)

{

 *((char*)ptr+i) = value;

}

return (char*)ptr;

}

int main()

{

int arr[10] = { 0 };

my_memset(arr, 'x', 39);

printf("%s",(char*)arr);

return 0;

}




  memest函数的第一个参数是被改数据的首地址,第二个参数是要改成的内容(整形家族),第三个参数是要改的字节数。






 虽然arr是整形数组,但通过memset函数可以以字节为单位,将它的每个字节的数据都改为字符型数据,所以memset函数的第二个参数只要是整形家族即可。


模拟实现

void* my_memset(void* ptr, int value, int num)

{

int i = 0;

for (i = 0; i < num; i++)

{

 *((char*)ptr+i) = value;

}

return (char*)ptr;

}

int main()

{

int arr[10] = { 0 };

my_memset(arr, 'x', 39);

printf("%s",(char*)arr);

return 0;

}




 博主写了好长时间,如果你能给博主一个免费三连鼓励一下博主的话,那么我觉得你的真是 泰     裤    辣 !!!


文章知识点与官方知识档案匹配,可进一步学习相关知识

相关文章
|
2月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
41 3
|
22天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
50 6
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
2月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
2月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
379 1
|
2月前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
2月前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(二)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
2月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
41 0
|
2月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
48 0
|
2月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
79 0