1. memcpy使用和实现
void * memcpy ( void * destination, const void * source, size_t num );
从源拷贝num个字节到目标内存的位置中,memcpy会直接对内存操作,所以遇到\0的时候不会停下来,如果源或目标的地址有人恶化重叠,复制的结构都是未定义的,如果确实需要拷贝会重叠的内存块,就交给memmove处理
官网资料:https://cplusplus.com/reference/cstring/memcpy/
因为我要拷贝的元素类型是不固定的,可能是整形,字符型,或者结构体类型,所以用void*来修饰前两个参数
模拟实现memcpy
2. memmove使用和实现
void * memmove ( void * destination, const void * source, size_t num );
官网资料:https://cplusplus.com/reference/cstring/memmove/
上面已将讲过,在处理源空间和⽬标空间出现重叠的内存块时就使用memmove函数,memmove和memcpy两个函数的声明长得一摸一样,这也说明它们的唯一不同就是在处理的问题情况上不一样
模拟实现memcpy
也许你现在还在疑惑为什么memcpy不能处理内存块有重叠的情况,事实上是因为内存重叠部分在处理的时候可能会出现这个位置的元素还没有拷走但是已经被覆盖了的情况
将sour位置的4拷到dest的位置的时候6被覆盖掉了,那么到拷sour的第3给元素的时候拷贝的就不是6而是4了,为了解决这个问题,我们才开发了memmove函数,通过观察规律,当dest的初始位置在sour之前应该从前向后拷贝,当dest的初始位置在sour之后应该从后向前拷贝,这样就能有效避免字符被覆盖掉的情况
通过两个函数的模拟实现我们可以发现memmove的功能要比memcpy的功能强大,内存重叠与否都可以拷贝过去,即使是两块不相关的内存memmove也可以很好的完成任务(虽然在道德上比较两个不相关的内存地址是应该被谴责的),所以在使用这两个库函数的时候,在两块内存很明确的不重叠的情况下可以用memcpy,其他情况可以一律使用memmove
3. memset内存设置函数的使用
void * memset ( void * ptr, int value, size_t num );
将ptr指向的内存块的第一个num字节设置为指定值value
官网资料:https://cplusplus.com/reference/cstring/memset/
值得注意的是,memset是一个字节一个字节进行设置操作的,所以在处理其他类型数据的时候要慎重
4. memcmp内存比较函数的使用
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节,当ptr1大就返回>0的值,如果ptr2的值大就返回<0的值,若都相同就返回0
官网资料:https://cplusplus.com/reference/cstring/memcmp/
因为有小端存储的规则,数字是倒着在4个字节中存放的,所以当+1了之后访问到了5和8,内存大小直接不一样了,所以ret2是小于0的数,下一篇博客我就会讲到小端存储和大端存储