⽬录:
1. memcpy使⽤和模拟实现
2. memmove使⽤和模拟实现及详解
3. memset函数的使⽤
4. memcmp函数的使⽤
正文:
1. memcpy使⽤和模拟实现
• 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
• 这个函数在遇到 '\0' 的时候并不会停下来。
• 如果source和destination有任何的重叠,复制的结果都是未定义的。
memcpy的实现:
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* a2, const void* a1, size_t n)
{
void* s = a2;
assert(s);
for (int i = 0; i < n; i++)
{
*((char*)a2) = *((char*)a1);
a2 = (char*)a2 + 1;
a1 = (char*)a1 + 1;
}
return s;
}
int main()
{
int a1[] = { 1,2,3,4,5,6,7,8,9 };
int a2[10] = { 0 };
my_memcpy(a2, a1, sizeof(a1[0])*4);
int i = 0;
for (i = 0; i < 4; i++)
{
printf("%d ", a2[i]);
}
return 0;
}
2. memmove使⽤和模拟实现及详解
• 和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。
• 如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。
memmove的实现及详解:
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* a1, const void* a2, int n)
{
void* s = a1;
assert(s);
if (a1 < a2)
{
for (int i = 0; i < n; i++)
{
*((char*)a1) = *((char*)a2);
a1 = (char*)a1 + 1;
a2 = (char*)a2 + 1;
}
}
else if(a1 == a2)
{
return s;
}
else
{
for (int i = 0; i < n; i++)
{
*((char*)a1 + n - i - 1) = *((char*)a2 + n - i - 1);
}
}
return s;
}
int main()
{
int a1[] = { 1,2,3,4,5,6,7,8,9 };
void* p = my_memmove(a1 , a1 + 2 , 4 * sizeof(a1[0]));
int i = 0;
for (i = 0; i < 9; i++)
{
printf("%d ", a1[i]);
}
return 0;
}
详解:
源空间(a2)和⽬标空间(a1)出现重叠的情况可大致分为两种情况:
1:a1 < a2
例如my_memmove(a1, a1 + 2,4*sizeof(a1[0]))
我们要把红色区域的内容移动到绿色区域,我们只需要从前往后依次移动一个字节, (注意:内存函数是以字节为单位的),所以我们需要将其强制转换为char*类型的指针。
2:a1 > a2
例如my_memmove(a1 + 2, a1,4*sizeof(a1[0]))
要将红色区域的内容移动到绿色区域,就不能跟第一种情况用相同的移动方法了,如果使用上面的方法会导致源空间的内容在移动之前被改变,结果如下:
这样的结果显然是我们不期望发生的,所以我们需要换一种角度思考,将元素从后往前移动,
3. memset函数的使⽤
memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
结果:
xxxxxxworld
4. memcmp函数的使⽤
• ⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节
• 返回值如下: