void *my_memcpy(void *dst, const void *src, size_t size)
{
char *psrc;
char *pdst;
if (nullptr == dst || nullptr == src)
{
return nullptr;
}
//出现地址重叠,从后向前拷贝
if ((src < dst) && (char *)src + size > (char *)dst)
{
psrc = (char *)src + size - 1;
pdst = (char *)dst + size - 1;
while (size--)
{
*pdst-- = *psrc--;
}
}
else
{
psrc = (char *)src;
pdst = (char *)dst;
while (size--)
{
*pdst++ = *psrc++;
}
}
return dst;
}
//附经典的strcpy
char *strcpy_de(char *dest, const char *src)
{
if (dest == nullptr && src == nullptr)
return nullptr;
char *tempDest = dest;
while ((*tempDest++ = *src++) != '\0'); //赋值后,先判断*tempDest的值是否是'\0',再自加1
return dest;
}
strcpy 函数有什么缺陷?
面试高频指数:★★☆☆☆
strcpy 函数的缺陷:strcpy 函数不检查目的缓冲区的大小边界,而是将源字符串逐一的全部赋值给目的字符串地址起始的一块连续的内存空间,同时加上字符串终止符,会导致其他变量被覆盖。
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int var = 0x11112222;
char arr[10];
cout << "Address : var " << &var << endl;
cout << "Address : arr " << &arr << endl;
strcpy(arr, "hello world!");
cout << "var:" << hex << var << endl; // 将变量 var 以 16 进制输出
cout << "arr:" << arr << endl;
return 0;
}
/*
Address : var 0x23fe4c
Address : arr 0x23fe42
var:11002164
arr:hello world!
*/
说明:从上述代码中可以看出,变量 var 的后六位被字符串 “hello world!” 的 “d!\0” 这三个字符改变,这三个字符对应的 ascii 码的十六进制为:\0(0x00),!(0x21),d(0x64)。
原因:变量 arr 只分配的 10 个内存空间,通过上述程序中的地址可以看出 arr 和 var 在内存中是连续存放的,但是在调用 strcpy 函数进行拷贝时,源字符串 “hello world!” 所占的内存空间为 13,因此在拷贝的过程中会占用 var 的内存空间,导致 var的后六位被覆盖。