下面主要对常用的几个memory库函数的实现(memcpy、memmove、memset、memcmp):
memcpy函数与memmove函数:
相同点:
两者实现的功能均为从src拷贝count个字符到dest。
不同点:
1、memcpy函数不考虑内存是否有覆盖的问题,也就是说他只负责完成拷贝工作,至于拷贝后的值正确与否,它是不理会的。
2、memmove函数考虑了内存覆盖的问题:1)当无覆盖情况时,功能及拷贝结果与memcpy函数相同;
2)当有内存覆盖时,能够确保拷贝后的值得正确性。
3、内存无覆盖及有覆盖的情况如下:
代码实现如下
//memcpy:内存拷贝函数,从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
char* my_memcpy(char* dst,const char* src,size_t count){ assert(dst != NULL); assert(src != NULL); assert(count <= strlen(src)+1); char* pDst = dst; const char* pSrc = src; while (count--) { *pDst = *pSrc; pDst++; pSrc++; } return dst;}--------------------------------------------------------------------------------------------------------------------------------------------
/* memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前
将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。*/
char* my_memmove(char* dst,const char* src,size_t count){ assert(dst != NULL); assert(src != NULL); assert(count <= strlen(src) + 1); char* pDst = dst; const char* pSrc = src; if (pDst > pSrc + count || pDst < pSrc)//不包含内存覆盖 { //正向拷贝 while (count--) { *pDst = *pSrc; pDst++; pSrc++; } } else//存在内存覆盖问题 { //反向拷贝(从尾到头) pDst += count; pSrc += count;
while (count--) { *pDst = *pSrc; pDst--; pSrc--; } } return dst;}
----------------------------------------------------------------------------------------------------------------------------------------------------------------
memset函数:将str所指内存区域的前count个字节设置成字符c。(注:该函数是对字节进行设置)
//memset内存设置函数:将str所指内存区域的前count个字节设置成字符c。
代码实现如下:void* my_memset(void* str, int c, int count){ assert(str != NULL); char* pStr = (char*)str; while (count--) { *pStr = c; pStr++; } return str;
}
1、情况一:对字符数组进行设置
int main()
{
char a[10];
memset(a , 0 , 10 );
} 数组a是字符型的,字符型占据内存大小是1Byte,而memset函数也是以字节为单位进行赋值的,所以你输出没有问题。
2、情况二:对整形数组进行设置
int main()
{
int b[10];
memset(b , 0 , 10 );
}
数组b是整型的,而使用 memset是按字节赋值,这样赋值完以后,每个数组元素的值实际上是0x01010101即十进制的16843009。而非想要的1。
3、 如果用memset(a,1,20),就是对a指向的内存的20个字节进行赋值,每个都用数1去填充,转为二进制后,1就是00000001,占一个字节。
一个int类型占4字节,合一起是0000 0001,0000 0001,0000 0001,0000 0001,转化成十六进制就是0x01010101,就等于16843009,
就完成了对一个int元素的赋值了。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//memcmp是比较内存区域str1和str2的前count个字节。该函数是按字节比较的。
int my_memcmp(const void *str1, const void *str2, size_t count){ if (str1 == NULL && str2 == NULL) { return 0; } const char* pStr1 = (const char*)str1; const char* pStr2 = (const char*)str2; int res = 0; for (pStr1, pStr2; count > 0; ++pStr1, ++pStr2, --count) { res = *pStr1 - *pStr2; if (res != 0) break; } return res;}