以下是 C 标准库中常用的 内存操作函数 的详细说明,
这些函数定义在头文件 <string.h>
中。
1. memcpy
原型:
void *memcpy(void *dest, const void *src, size_t n);
功能:
将 src
所指向的内存区域的前 n
个字节复制到 dest
所指向的内存区域。
⚠️ 注意:不能用于重叠内存区域(使用 memmove
替代)。
参数:
dest
:目标内存地址。src
:源内存地址。n
:要复制的字节数。
返回值:
返回指向 dest
的指针。
memcpy
函数不能用于重叠的内存区域的原因主要在于其底层实现机制。为了更好地理解这个问题,我们需要了解 memcpy
是如何工作的。
memcpy
的工作原理
memcpy
函数通常按照从低地址到高地址的方向进行复制操作。这意味着它会从源内存块 (src
) 的起始位置开始读取数据,并将这些数据写入目标内存块 (dest
) 的起始位置,然后逐步向后移动指针直到完成指定字节数 (n
) 的复制。
如果源和目标内存区域存在重叠,目标地址在源地址之后(目标地址 > 源地址),那么在复制过程中,还未被复制的数据可能会被覆盖,从而导致数据丢失或复制结果不正确。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello World";
char dest[20];
memcpy(dest, src, strlen(src) + 1); // 包括 '\0'
printf("dest: %s\n", dest);
memcpy(src + 2, src, 10); // 不符合预期
return 0;
}
2. memmove
原型:
void *memmove(void *dest, const void *src, size_t n);
功能:
与 memcpy
相同,但可以安全地处理重叠内存区域。
它会根据源和目标地址的关系选择适当的复制方向(从前向后或从后向前),从而避免数据丢失。
3. memset
原型:
void *memset(void *str, int c, size_t n);
功能:
将 str
指向的内存块的前 n
个字节设置为值 c
(按字节设置)。
参数:
str
:要填充的内存地址。c
:要设置的值(以int
形式传入,实际使用其低8位)。n
:要设置的字节数。
返回值:
返回指向 str
的指针。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char buffer[20];
memset(buffer, 'A', 10); // 前10个字节设为 'A'
buffer[10] = '\0'; // 手动添加终止符
printf("buffer: %s\n", buffer);
return 0;
}
4. memcmp
原型:
int memcmp(const void *s1, const void *s2, size_t n);
功能:
比较两个内存块的前 n
个字节内容。
参数:
s1
,s2
:要比较的两个内存块。n
:要比较的字节数。
返回值:
- 小于 0:如果
s1
小于s2
- 等于 0:如果
s1
等于s2
- 大于 0:如果
s1
大于s2
示例:
#include <stdio.h>
#include <string.h>
int main() {
char a[] = "abcde";
char b[] = "abXde";
int result = memcmp(a, b, 5);
if (result < 0)
printf("a is less than b\n");
else if (result == 0)
printf("a equals b\n");
else
printf("a is greater than b\n");
return 0;
}
5. memchr
原型:
void *memchr(const void *str, int c, size_t n);
功能:
在内存块 str
的前 n
个字节中查找字符 c
(作为无符号字符)第一次出现的位置。
参数:
str
:要搜索的内存块。c
:要查找的字符(以int
形式传入)。n
:要检查的最大字节数。
返回值:
- 成功:返回指向找到字符的指针。
- 失败:返回
NULL
。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char data[] = "This is a sample string.";
char *found = memchr(data, 's', strlen(data));
if (found)
printf("Found 's' at position: %ld\n", found - data);
return 0;
}