C语言 内存函数
前言:C语言提供了许多与内存相关函数,可以在头文件<string.h>中查看函数声明,本章将会自行编写相关内存函数
一、内存复制函数
1.1 memcpy函数
功能:
将num字节的值从source指向的位置直接拷贝到destination指向的内存块,该函数不检查源中是否有’\0’字符——它总是精确地复制num字节。但是source与destination发生内存重叠,结果是未定义的
库函数memcpy声明void * memcpy ( void * destination, const void * source, size_t num );
返回值:返回目标起始位置
destination :目标指向内存块起始地址
source:源指向内存块起始地址
num :需要复制的字节数
模拟实现
1 | void* my_memcpy(void* destination, const void* source, size_t num) |
警告:
如果源与目标以任何形式发生内存重叠,它的结果是未定义的。当发生内存重叠应该使用memmove函数而不是memcpy函数
例:int arr[10] = {1,2,3,4,5,6,7,8,9,10}
将数组下标0-3对应元素值依次复制到下标2-5对应元素
预想复制后数组为int arr[10] = {1,2,1,2,3,4,7,8,9,10},但实际数组为int arr[10] = {1,2,1,2,1,2,7,8,9,10}。
因为从下标第2-3元素发生内存重叠。复制后下标2元素为1,下标3元素为2,所以下标为4元素值变为1,下标为5元素值变为2

1 |
|
输出
1 | 1 2 1 2 1 2 7 8 9 10 |
1.2 memmove函数
功能:
将num字节的值从source指向的位置直接拷贝到destination指向的内存块,该函数不检查源中是否有’\0’字符——它总是精确地复制num字节。source与destination可以发生内存重叠
库函数memmove声明void * memmove ( void * destination, const void * source, size_t num );
返回值:返回目标起始位置
destination :目标指向内存块起始地址
source:源指向内存块起始地址
num :需要复制的字节数
memmove函数允许source与destination可以发生内存重叠。那么在复制时有三种处理方式
情况1: source地址 <** destination地址 时将**从后向前**复制
情况2: source地址 **> destination地址 时将从前向后复制
情况3: source地址 == destination地址时,从前向后或从后向前复制都可以,本案例会采用从前向后复制
模拟实现
1 | void * my_memmove(void * destination, const void * source, size_t num) |
测试
1 |
|
输出
1 | arr1:> |
二、内存比较函数 memcmp
功能:
memcmp对两段内存中的内容进行比较,两段内存分别起始ptr1和ptr2,共比较num个字节。当num个字节内容相等返回0,ptr1大于ptr2返回大于0值,ptr1小于ptr2返回小于0的值
库函数memcmp声明int memcmp ( const void * ptr1, const void * ptr2, size_t num );
ptr1 : 第一段内存起始地址
ptr2: 第二段内存起始地址
num: 比较字节个数
模拟实现
1 | int my_memcmp(const void * ptr1, const void * ptr2, size_t num) |
三、内存查找字符函数 memchr
功能:
从ptr开始向后查找字符value第1次出现的位置,并返回一个指向该位置的指针,它最多向后搜寻num个字节。如果未找到,返回NULL指针
库函数memchr声明const void * memchr ( const void * ptr, int value, size_t num );
ptr:待搜索内存起始位置
value :需要查找字符
num :要搜寻的字节个数
模拟实现
1 | const void * my_memchr(const void * ptr, int value, size_t num) |
四、内存设置函数 memset
功能
把从ptr开始的num个字节都设置为字符值value
库函数memset声明void * memset ( void * ptr, int value, size_t num );
ptr: 待设置内存起始位置
value :设置字符值
num :要设置字节的个数
模拟实现
1 | void* my_memset(void* ptr, int value, size_t num) |