memcpy、memset、memmov等内存操作函数介绍及其源码实现

1. memset

函数源码实现

void *memset(void *s, int c, size_t n)
{
	char *xs = s;

	while (n--)
		*xs++ = c;
	return s;
}

功能:把 s所指向的某一块内存空间,使用字符c来进行填充,填充长度是n。该函数通常在我们申请一块新的内存时,用来清零;或者我们定义一个大的结构体、数组的时候,使用memset进行清零操作。

参数

  1. s: 要填充的内存首地址
  2. c: 该块内存要填充的值
  3. n: 要填充的长度

返回值:返回要填充的内存首地址,即传入的指针s

2. memcpy

函数源码实现

void *memcpy(void *dest, const void *src, size_t n)
{
	char *tmp = dest;
	const char *s = src;

	while (n--)
		*tmp++ = *s++;
	return dest;
}

功能:把 src所指向的内存,复制n个字节到dest所指向的内存。

参数

  1. dest: 目标存储空间的首地址
  2. src: 要复制的数据源的首地址
  3. n: 要从src所指的内存中复制长度

返回值:返回目标存储空间的首地址,即dest

注意事项:如果源内存空间和目标内存空间有重叠时,memcpy是无法保证内存复制的正确性的

3. memmove

memmove函数和memcpy函数都是内存复制函数,他们在用法上也一样。但是如果目标区域和源区域有重叠的话,memmove 是比 memcpy 更安全的方法,memmove 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy 函数功能是完全相同的。

函数源码实现

void *memmove(void *dest, const void *src, size_t n)
{
	char *tmp;
	const char *s;

	if (dest <= src) {
		tmp = dest;
		s = src;
		while (n--)
			*tmp++ = *s++;
	} else {
		tmp = dest;
		tmp += n;
		s = src;
		s += n;
		while (n--)
			*--tmp = *--s;
	}
	return dest;
}

功能:把 src所指向的内存,复制n个字节到dest所指向的内存。功能其实和memcpy函数一样,但是memmove函数考虑了内存重叠的情况,所以memmove函数更安全。

参数

  1. dest: 目标存储空间的首地址
  2. src: 要复制的数据源的首地址
  3. n: 要从src所指的内存中复制长度

返回值:返回目标存储空间的首地址,即dest

4. memcmp

memcmp函数就是比较两块内存的前n个字节的数据大小的。函数原型和功能都与strncmp函数非常的相似,但是还是有一些不同的。

  1. memcmp比较两个字符串的大小的话,如果两个字符串的长度都比n这个参数要小的话,遇到’\0’也不会结束比较,直到n为0,才会结束比较(如果前面就已经比较出了结果,则另说)。
  2. 对于strncmp则会在最短的字符串停下来,比较完成

函数源码实现

int memcmp(const void *s1, const void *s2, size_t n)
{
	const unsigned char *su1, *su2;
	int res = 0;

	for (su1 = s1, su2 = s2; 0 < n; su1++, su2++, n--)
		if ((res = *su1 - *su2) != 0)
			break;
	return res;
}

功能:对s1和s2两块存储区的前n个字节进行比较

参数

  1. s1: 第一块存储区的首地址
  2. s2: 第二块存储区的首地址
  3. n: 要比较的最大字节数

返回值

  1. 如果返回值小于 0,则表示 str1 小于 str2
  2. 如果返回值大于 0,则表示 str1 大于 str2
  3. 如果返回值等于 0,则表示 str1 等于 str2

5. memchr

函数源码实现

void *memchr(const void *s, int c, size_t n)
{
	const unsigned char *p = s;
	while (n-- != 0) {
        	if ((unsigned char)c == *p++) {
			return (void *)(p - 1);
		}
	}
	return NULL;
}

功能:在参数s所指向的内存区域中,搜索前n个字节的长度第一次出现字符c的位置。

参数

  1. s: 要搜索的内存区域的首地址
  2. c: 要搜索的字符
  3. n: 要搜索的最大字节数

返回值

  1. 成功则返回所匹配字符的地址
  2. 失败返回NULL

版权声明:本文为luobeihai原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。