常用的内存管理函数有以下这四位↓
malloc、callco、relloc、free
想要这四位的帮助都需要都需要引入一个头文件stdlib.h
目录
函数原型
用法演示
malloc和calloc注意事项
realloc注意事项
malloc与calloc的对比
函数原型
来看看他们的函数原型
malloc函数原型
void* malloc (size_t size);
这个void并不是无返回类型!看看他后面的小星星,这是无类型指针,所以他是有一个无类型指针的返回值,括号里的参数为无符号整形。
callco函数原型
void* calloc (size_t num, size_t size);
他的返回类型同样为无类型指针,他的括号里的参数为两个无符号整形。
realloc函数原型
void* realloc (void* ptr, size_t size);
他的返回类型同样为无类型指针,他的括号里有两个参数一个无类型指针和一个无符号整形
上面三个函数都是按照字节数来开辟空间的
free函数原型
不过free函数不是用来开辟空间的
void free (void* ptr);
这次就是无返回值啦,括号里的参数只有一个无类型指针。
用法演示下面来演示下他们的用法
malloc使用方法
#include
#include
int main()
{
//在堆空间中开辟空间
//使p指向这段开辟的空间
int* p = (int*)malloc(10 * sizeof(int)); //开辟十个int类型的大小
//返回值不强制转换的话有些编译器可能会报警告
int i;
for (i = 0; i < 10; i++)
{
printf("%d ", *(p+i) = i);
}
//空间回收
free(p); //这里只是把这段内存还给了操作系统p没有置为空指针,p还是指着这个空间
p = NULL; //需要手动置为空指针,免得后面误操作
return 0;
}
看看打印结果
callco使用方法
#include
#include
int main()
{
//↓和malloc一样也是在堆中开辟空间
//和malloc不同的是他不用乘10了,两个参数第一个无符号整形就是你要乘的数
int* p = (int*)calloc(10,sizeof(int));
int i;
//直接打印看看结果
for (i = 0; i < 10; i++)
{
printf("%d ",*(p+i) = i);
}
printf("\n");
free(p);
p = NULL;
return 0;
}
看看打印结果
reallco的使用方法就有些不同了,他是用来改变前面两个函数开辟好的空间大小
#include
#include
int main()
{
int* p = (int*)calloc(10,sizeof(int));
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = 2;
}
//诶,我觉得光有十个2不够还想再来十个3,那么就得扩容了
//这时就要用到realloc函数了
//现在就把这段空间改为20个字节
realloc(p, 20 * sizeof(int));
//这样就能继续加值了
for (i = 10; i < 20; i++)
{
*(p + i) = 3;
}
for (i = 0; i < 20; i++)
{
printf("%d",*(p+i));
}
free(p);
p = NULL;
return 0;
}
看看打印结果
我想大家都应该注意到了上面的演示中都有free,没注意到也没关系,我现在说了,可以返回去注意下
都是在结尾用的是用来干嘛的呢?看看他里面的指针,都是指向这段开辟的空间,这时我们看看free的翻译
这段意思好像就是在说这段空间放飞自我了,其实不是,free的作用就是释放掉这段空间的内容把这段空间还给系统,然后这段空间就归系统管了,但是free只是把这段空间还给了 *** 作系统,他并没有把p置为空指针,要是之后忘记p是用来干嘛的了,你又去动动他,那你应该就成功的获得了一个bug吧,所以需要在后面手动把p置为空指针
malloc和calloc注意事项上面的的函数都有可能返回空指针,如果直接用上面的p接收他们的返回值接收到一个空指针,那又去用p *** 作空指针,那肯定会出问题的,一般都是内存不够用的时候才会返回空指针,下面来看看会返回空指针的例子
#include
#include
int main()
{
int* p = (int*)malloc(1000000000000 * sizeof(int)); //开辟~个int类型的大小
//返回值不强制转换的话有些编译器可能会报警告
if (p == NULL)
{
//↓开辟失败的话就用下面这个函数打印下错误信息,这个函数的使用方法我在这就不细讲了
perror("main");
return 0;
}
int i;
for (i = 0; i < 10; i++)
{
printf("%d ", p[i] = i);
}
//空间回收
free(p); //这里只是把这段内存还给了操作系统p没有置为空指针,p还是指着这个空间
p = NULL; //需要手动置为空指针,免得后面误操作
return 0;
}
看看打印结果
错误信息打印出来了 ,英文?看不懂没关系用用翻译软件翻译翻译,这段话告诉你空间不足
下面就来改造下malloc和calloc函数
#include
#include
int main()
{
int* p = (int*)malloc(10 * sizeof(int)); //开辟十个int类型的大小
//返回值不强制转换的话有些编译器可能会报警告
//加个if判断如果是空指针就直接打印错误信息然后直接return
if (p == NULL)
{
//↓开辟失败的话就打印下错误信息,这个函数的使用方法我在这就不细讲了
perror("main");
return 0;
}
int i;
for (i = 0; i < 10; i++)
{
printf("%d ", p[i] = i);
}
//空间回收
free(p); //这里只是把这段内存还给了操作系统p没有置为空指针,p还是指着这个空间
p = NULL; //需要手动置为空指针,免得后面误操作
return 0;
}
#include
#include
int main()
{
int* p = (int*)calloc(10,sizeof(int));
int i;
//直接打印看看结果
if (p == NULL)
{
perror("main");
return 0;
}
for (i = 0; i < 10; i++)
{
printf("%d ",p[i] = i);
}
printf("\n");
free(p);
p = NULL;
return 0;
}
简单吧
realloc注意事项reallco我单独拿出来讲
reallco是帮malloc和calloc改变空间大小的,用法呢上面也说了但是注意看看realloc的函数型,他是有个返回值的,这可不是摆设,他返回的是开辟后空间的地址,为什么要有返回地址?不是扩大了吗?下面就来讲解下。
举个例子
这是一段空间
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
黄色是开辟的空间红色是系统要使用的空间,如果我再往后扩大不就动到系统空间了吗?
这时realloc就会重新开辟一段足够大的空间并把上面的数据都放到这段空间里然后再返回这段新空间的地址、那么原先空间不足的地址里的内容就会被释放掉,这时如果你再用p *** 作这段空间的地址那肯定会出问题的所以我们就直接用p指向新空间的地址如下↓
int*p = (int*)realloc(p, 20 * sizeof(int));
使p指向新空间就完了吗?当然不是,这个函数开辟失败的话也是会返回空指针的,所以可以先判断下他的返回值是否为空指针,如果不是null再让p指向新地址。
现在上升级后的代码↓
#include
#include
int main()
{
int* p = (int*)calloc(10,sizeof(int));
if (p == NULL)
{
perror("main");
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = 2;
}
//诶,我觉得光有十个2不够还想再来十个3,那么就得扩容了
//这时就要用到realloc函数了
//这里我们再创建一个指针用于接收realloc的值
int*p2 = (int*)realloc(p, 20 * sizeof(int));
//然后再判断下这个值是不是为空指针
if (p2 != NULL)
{
p = p2;
}
else
{
perror("main");
return 1;
}
//这样就能继续加值了
for (i = 10; i < 20; i++)
{
*(p + i) = 3;
}
for (i = 0; i < 20; i++)
{
printf("%d",*(p+i));
}
free(p);
p = NULL;
return 0;
}
看看打印结果
malloc与calloc的对比mallco和calloc使用法都是一样的哪他们有什么区别呢
直接上代码开结果进行说明
#include
#include
int main()
{
//↓和malloc一样也是在堆中开辟空间
int* p = (int*)calloc(10,sizeof(int));
//但是和malloc函数不同的是它会自动把这段空间初始化为0;
//malloc是不会初始化为0的
int i;
//直接打印看看结果
if (p == NULL)
{
perror("main");
return 0;
}
for (i = 0; i < 10; i++)
{
printf("%d ",p[i]);
}
printf("\n");
free(p);
p = NULL;
//做个对比
printf("--------------------对比----------------\n");
p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
perror("main");
return 0;
}
for (i = 0; i < 10; i++)
{
printf("%d ",p[i]);
}
free(p);
printf("\n");
p = NULL;
return 0;
}
看看打印结果
这就看出区别了吧
calloc会把开辟空间里的内容初始化为0,而malloc则不会,还是一串没初始化意义不明的数字
以上就是我对四个内存管理函数的理解,如果有什么讲错的地方都可以告诉我,有什么不明白的地方也可以和我说说,感谢各位的阅读。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)