内存操作
我们对于内存操作需要依赖于string.h
头文件中相关的函数库。
内存操作函数
内存填充
-
头文件:
#include <string.h>
-
函数原型:
void* memset(void *s,int c,size_t n)
-
函数功能:将内存块
s
的前n
个字节填充为c
,一般用于初始化或者清零操作。 -
参数说明:
s
:目标内存首地址c
:填充值(以unsigned char形式处理(0~255)))n
:填充字节数
-
返回值:
- 成功:返回s的指针
- 失败:返回NULL
-
注意事项:
- 常用于动态化初始化,c通常设置为0(清零)
- 按字节填充,非整型初始化需要谨慎(如填充it数组时,0是安全的)
-
案例:
/*************************************************************************
> File Name: demo01.c
> Author: 小刘
> Description:
> Created Time: 2025年05月26日 星期一 10时02分49秒
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[])
{
// 在堆内存中申请4个int的连续空间
int *p = (int*)malloc(4 * sizeof(int));
// 非空校验
if(p == NULL)
{
perror("内存申请失败!");//perror不需要加换行符,它可以自己换行
return -1;
}
// 初始化堆内存,填充0
memset(p,0,4 * sizeof(int));//默认初始中值为0,例如:填充后两个memset(p + 2,0,);
// 测试输出
printf("%d\n",p[1]);
// p[1] 的底层实现 *(p+1) 我们可以将p[1]看作是 *(p+1) 语法糖
// 内存使用完毕要,释放
free(p);
// 对指针赋值NULL
p = NULL;
return 0;
}
内存拷贝
-
头文件:
#include <string.h>
-
函数原型:
-
源与目标内存无重叠时使用
void* memcpy(void* dest, const void* src,size_t n);
-
安全处理内存重叠
void* memmove(void* dest, const void* src,size_t n);
-
-
函数功能:将
stc
的前n
个字拷贝到dest
-
参数说明:
dest
:目标内存首地址stc
:源内存首地址size_t n
:拷贝的字节数
-
返回值:
- 成功:返回
dest
的首地址 - 失败:返回NULL
- 成功:返回
-
注意事项:
memmove
能正确处理内存重叠,推荐优先使用- 确保目标内存足够大,避免溢出。
-
示例
/*************************************************************************
> File Name: demo02.c
> Author: 小刘
> Description:
> Created Time: 2025年05月26日 星期一 10时45分19秒
************************************************************************/
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
// 准备两个数组,用来存储和目标
int src[4] = {11,22,33,44};
int dest[6] = {111,222,333,444,555,666};
// 进行拷贝
// memcpy()
memmove(dest+1,src+1,2 * sizeof(int));
printf("源数组:");
register int i;
for(i = 0; i < 4; i++)printf("%-6d",src[i]);
printf("\n目标数组:");
for(i = 0; i < 4; i++)printf("%-6d",dest[i]);
printf("\n");
return 0;
}
思考:什么是内存重叠?
内存比较
-
头文件:
#include <string.h>
-
函数原型:
int memcmp(const void* s1, const void* s2,size_t n);
-
函数功能:比较
s1
和s2
的前n
个字节 -
返回值:
0
:内存内容相同>0
:s1
中第一个不同字节大于s2
<0
:s1
中第一个不同字节小于s2
-
注意事项:比较按字节进行,非字符串需确保长度一致(总字节数一致)。
-
示例:
/************************************************************************* > File Name: demo03.c > Author: 刘孟丹 > Description: > Created Time: 2025年05月26日 星期一 11时20分03秒 ************************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { // 准备比较的数据 int* arr1 = (int *)malloc(3 * sizeof(int));//3个元素 int* arr2 = (int *)calloc(4 , sizeof(int));//4个元素 // 清零 memset(arr1,0,3 * sizeof(int)); // 赋值 arr1[0] = 60;arr2[1] = 66; arr2[0] = 70;arr2[1] = 5; // 比较 int cmp_result = memcmp(arr2,arr1,2* sizeof(int)); printf("比较结果:%d-(%s)\n",cmp_result,cmp_result > 0 ?"大于":cmp_result < 0 ?"小于" :"等于"); free(arr1); free(arr2); arr1 = arr2 = NULL; return 0; }
内存查找
-
头文件:
#include <string.h>
-
函数原型:
- 正向查找:C语言标准
void* mem(void* dest, const void* src,size_t n);
-
反向查找
void* memchar(void* dest, const void* src,size_t n);
-
函数功能:在
s
的前n
个字节中查找字符c
-
返回值:
- 成功:返回找到内容对应地址
- 失败:返回NULL
-
注意事项:
memch
- 是GNU扩展函数,需手动声明(只要不是C语言标准提供,编译的时候都需要手动声明或链接)
- 查找单位为字节值,非整型数据需要注意内存布局
-
示例:
/************************************************************************* > File Name: demo04.c > Author: 刘孟丹 > Description: > Created Time: 2025年05月26日 星期一 11时41分52秒 ************************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> extern void* memchr(const void*,int,size_t); extern void* memrchr(const void*,int,size_t); int main(int argc,char *argv[]) { //准备一个测试数组 char str[] = {'A','B','C','B'}; // 查找字符‘B’ char *first = (char*) memchr(str,'B',sizeof(str)); char *last = (char*) memrchr(str,'B',sizeof(str)); printf("first= %p,last=%p\n",first,last); printf("第一个B的位置,%ld\n",first - str); printf("最后一个B的位置,%ld\n",last - str); return 0; }