一、memcpy函数说明
还是老惯例,cplusplus的网址在这里啦,家人们保存好哟!
函数总结:
-
功能:
- 将
num
字节的数据从source
指向的位置直接复制到destination
指向的内存块。
- 将
-
直接复制:
- 数据复制是直接进行的,没有使用中间缓冲区。
-
数据类型无关性:
- 函数在复制数据时不关心
source
和destination
指针所指向对象的底层类型。
- 函数在复制数据时不关心
-
二进制复制:
- 数据以二进制形式复制,不检查
source
中是否有终止空字符(null terminator)。
- 数据以二进制形式复制,不检查
-
不检查溢出:
- 函数不检查目标数组是否有足够的空间,因此调用者需要确保目标数组足够大。
-
内存重叠问题:
- 如果
destination
和source
指向的内存区域有重叠,使用memcpy
可能会导致数据损坏。在这种情况下,应使用memmove,库函数的模拟实现(memmove)
。
- 如果
-
参数类型:
destination
是指向目标数组的指针,类型转换为void*
。source
是指向要复制的数据源的指针,类型转换为const void*
。num
是要复制的字节数,类型为size_t
(无符号整型)。
-
返回值:
- 函数返回
destination
指针。
- 函数返回
-
内存大小要求:
- 为了避免溢出,
destination
和source
指向的数组的大小至少应该是num
字节,且这两个数组不应该重叠。
- 为了避免溢出,
-
错误处理:
- 函数本身不进行错误检查,因此调用者需要确保传入的参数有效,且内存区域足够大以容纳复制的数据。
使用 memcpy
时,开发者需要确保提供的内存区域大小合适,并且正确处理任何可能的内存重叠问题,以避免数据损坏或程序崩溃。如果内存区域可能重叠,应优先使用 memmove
函数。
二、memcpy函数使用
为了让大家更加了解这个函数我们现在来使用一下
#include <stdio.h>
#include <string.h> // 包含memcpy函数的头文件int main() {// 定义两个整型数组int sourceArray[] = {10, 20, 30, 40, 50};int destinationArray[5] = {0}; // 初始化为0// 使用memcpy从sourceArray复制5个int大小的数据到destinationArraymemcpy(destinationArray, sourceArray, sizeof(sourceArray));// 打印destinationArray的内容以验证复制是否成功printf("Copied array elements:\n");for (int i = 0; i < 5; i++) {printf("%d ", destinationArray[i]);}printf("\n");return 0;
}
这段代码首先包含了 string.h
头文件,这是使用 memcpy
函数所必需的。然后定义了两个整型数组 sourceArray
和 destinationArray
。sourceArray
包含了要复制的数据,而 destinationArray
是目标数组,用于存储复制的数据。
我们使用 memcpy
函数将 sourceArray
的内容复制到 destinationArray
。复制的字节数是通过 sizeof(sourceArray)
计算得来的,这确保了整个数组被复制。
复制完成后,使用一个循环和 printf
函数打印 destinationArray
的内容,以验证复制操作是否成功。
三、memcpy模拟实现
到了本期文章的重头戏啦,我们来根据前面对函数的总结进行模拟实现吧。
#include <stdio.h>
#include <assert.h>
#include <string.h>void* my_memcpy(void* dest, const void* src, size_t n) {assert(dest && src && n > 0); // 确保所有参数有效void* ret = dest;unsigned char* d = (unsigned char*)dest;const unsigned char* s = (const unsigned char*)src;for (size_t count = n; count > 0; --count) {*d++ = *s++;}return ret;
}int main() {int a[] = {1, 2, 3};int b[10] = {0};// 使用 my_memcpy 函数复制 a 数组到 b 数组size_t n = sizeof(a) / sizeof(a[0]); // 计算 a 数组的元素个数my_memcpy(b, a, n);// 打印 b 数组的内容size_t sz = sizeof(b) / sizeof(b[0]);for (size_t i = 0; i < sz; i++) {printf("%d ", b[i]);}printf("\n");return 0;
}
代码详解:
-
自定义
my_memcpy
函数:- 函数原型:
void* my_memcpy(void* dest, const void* src, size_t n)
,接受三个参数,分别代表目标内存地址、源内存地址和要复制的元素个数。 assert(dest && src && n > 0)
:确保dest
和src
非空且n
大于 0,这是为了确保内存复制的安全性。
- 函数原型:
-
函数返回值:
void* ret = dest
:保存目标地址,以便最后返回。
-
内存复制逻辑:
- 将
dest
和src
转换为unsigned char*
类型的指针,以便按字节操作。 - 使用一个循环,从
n
开始递减至 0,每次循环中将src
指向的字节复制到dest
指向的位置,然后递增两个指针。
- 将
-
返回目标地址:
- 函数返回目标地址
ret。
- 函数返回目标地址
-
使用
my_memcpy
:- 计算
a
数组的元素个数n
,并将其作为参数传递给my_memcpy
函数,同时传递a
和b
的地址。这将复制a
的内容到b
。
- 计算
本期内容到此结束啦,大家自己动手试试吧。