内存拷贝,移动和设置这三个函数在实现中充分体现了void类型指针的特点,对与void指针有问题的可以戳无类型void*指针的几大特性查看。
下来是我模拟实现的内存操作函数
函数原型:void * memmove(void * _Dst, const void * _Src, size_t _Size);
参数说明:_Dst指针为目标指针; _Src为源指针;_Size为移动的距离
void* my_memove(void* dest, const void* src, size_t count)
{
assert(dest&&src);
char *tmp_dest = (char*)dest;
char *tmp_src = (char*)src;
if (dest<=src||(char*)dest>=(char*)src+count)//不会出现内存重叠,从低地址开始拷贝
{
while (count--)
{
*tmp_dest++ = *tmp_src++;
}
}
else//为避免内存重叠带来的缺陷,从高地址拷贝
{
tmp_dest = tmp_dest + count - 1;
tmp_src = tmp_src + count - 1;
while (count--)
{
*tmp_dest--= *tmp_src--;
}
}
return dest;
}
由 _Src指向地址为起始地址的连续count个字节的数据复制到以_Dst指向地址为起始地址的空间内。 _Src和_Dst两者所指向的地址不能有重叠,不然会出现内存重叠,拷贝不成功
函数原型:void *memcpy(void * _Dst, const void * _Src,size_t _Size);
参数说明:_Dst指针为目标指针; _Src,为源指针; _Size为拷贝的字节长度
#include
#include
struct Student
{
char s_id[20];
char s_name[20];
char s_sex;
int age;
};
void* my_memcpy(void* dest, const void* src, size_t count)
{
assert(src != nullptr&&dest != nullptr);
//判断dest指针和src指针是否为空,若为空抛出异常
char* tmp_dest = (char*)dest;
const char* tmp_src = (const char*)src;
//将指针dest和指针src由void强转为char,
//使得每次均是对内存中的一个字节进行拷贝
while (count--)
*tmp_dest++ = *tmp_src++;
return dest;
}
int main()
{
int ar[10] = { 12, 23, 34, 45, 56, 67, 78, 89, 90, 100 };
int ar1[10];
Student s1;
Student s = { "20186787", "dasyi", 'm', 43 };
my_memcpy(ar1, ar, sizeof(ar));
for (int i = 0; i < 10; i++)
{
printf("%d ", ar1[i]);
}
printf("\n");
my_memove(ar1, ar, sizeof(ar));
for (int i = 0; i < 10; i++)
{
printf("%d ", ar1[i]);
}
printf("\n");
my_memcpy(&s1, &s, sizeof(s1));
printf("%s %s %c %d\n", s1.s_name, s1.s_id, s1.s_sex, s1.age);
my_memove(&s1, &s, sizeof(s1));
printf("%s %s %c %d\n", s1.s_name, s1.s_id, s1.s_sex, s1.age);
return 0;
}
函数原型:void * memset(void * _Dst, _ int _Val, _ size_t _Size);
参数说明:_Dst指针为目标指针;_Val为内存中设置的值; _Size为设置的内存长度
void *my_memset(void *sd, int val, int n)
{
if (NULL == sd || n < 1)return sd;
char *tmp = (char *)sd;
while (n--)
{
*tmp++ = (char)val;
}
return sd;
}
int main()
{
char ar[10];
int br[10];
my_memset(br, 1, 40);
for (int i = 0; i < 10; i++)
{
printf("%x\n",br[i]);
}
return 0;
}
测试结果:每个字节都为val
内存移动函数和内存拷贝函数应用于内存增容。步骤如下:
1,重新分配大空间给同类型指针p。
2,将数据复制进新空间,然后将原来指针(t.data)j解放出来,即free(t.data);t.data=NULL;
3,将内存容量更新
bool Inc_Size(Seqlist&t)
{
//t.data = (Elemtype *)realloc(t.data, sizeof(Elemtype)*(GetCapcity(t)*2));
Elemtype*p = (Elemtype *)malloc(sizeof(Elemtype)*GetCapcity(t)* 2);
if (t.data)
{
for (int i = 0; i < t.cursize; i++)
{
memcpy(p, t.data, sizeof(t.data));
}
free(t.data);
t.data = NULL;
t.data = p;
t.maxsize = GetCapcity(t);
return true;
}
else
{
return false;
}
}