前言:相信大家对静态内存开辟都不陌生,如以下两行代码
int a = 0; //在栈空间上开辟4个字节的空间
char b[10] = {
0 }; //在栈空间上开辟10个字节的连续空间
它们具有如下特点:
1.空间开辟的大小是固定的。
2.数组在声明的时候,数组的长度必须提前指定,且它所需要的内存在编译时分配。
但是对于空间的需求是灵活多变的,有时我们需要的空间大小只有在程序运行的时候才能知道,那么上述数组的编译时开辟空间的方式就不能满足需求了。这种时候,就可以使用动态内存开辟,下面将介绍与之有关的几个函数及其使用方式,保证一看就会,迅速上手。
malloc,calloc,realloc,free函数
头文件:#include<stdlib.h>
malloc功能:在堆区开辟一段连续的动态内存空间。
calloc功能:在堆区开辟一段连续的动态内存空间,同时将每个字节初始化为0。
realloc功能:对动态开辟的内存大小进行调整。
free:使用起来及其简单,仅需在代码结尾使用一下将开辟的动态内存空间释放,使用形式:free(开辟的动态内存空间的起始地址)
在下文中不再单独解释。
malloc
cplusplus介绍如下:(下图仅供参考,看不懂也没关系)
1.
malloc仅有一个参数,就是需要开辟内存空间的大小(单位是字节)
,但它是无符号类型,所以在使用时需要将它变成我们需要的符号类型。
2.若开辟空间成功,则返回一个指向起始位置的指针,若开辟空间失败,则返回一个空指针。
通过图文和代码示例,一目了然:
#include<stdio.h>
#include<stdlib.h> //不要忘了引用头文件
int main()
{
int* p = (int*)malloc(12); //开辟一块12个字节的动态内存空间
free(p); //释放动态内存空间
return 0;
}
这样就完成了动态内存的开辟,是不是非常简单?
malloc使用方式
malloc函数开辟的是一块连续的动态内存空间,这是不是与我们之前学过的数组非常相似,不错,实际上使用时将其想象成数组使用即可。
请看如下代码:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(40); //开辟40个字节的空间
int i = 0;
for (i = 0; i < 10; i++)
{
//进行赋值操作
p[i] = i + 1; //数组形式,与上一行意义相同
}
for (i = 0; i < 10; i++)
{
printf("%d ", p[i]); //打印
}
free(p); //释放动态内存空间
p = NULL; //对p置空,可以不加。
return 0;
}
打印结果:
calloc
与malloc及其相似,只是多了一个参数,并且会将每个字节初始化为0.
cplusplus介绍如下:(下图仅供参考,看不懂也没关系)
1.calloc具有两个参数,第一个参数为要开辟内存的元素个数,第二个参数为每个元素的大小(单位是字节)
2.若开辟空间成功,则返回一个指向起始位置的指针,若开辟空间失败,则返回一个空指针。
calloc使用方式
因此与malloc相似,就不再进行图文详细介绍,不懂的朋友请看malloc的图文介绍。
这里仍以上面的代码为例:
#include<stdio.h>
#include<stdlib.h>
int main()
{
//仅此处进行了修改,开辟10个整型的动态内存空间,每个整型大小为sizeof(int)
int* p = (int*)calloc(10,sizeof(int));
int i = 0;
for (i = 0; i < 10; i++)
{
p[i] = i + 1;
}
for (i = 0; i < 10; i++)
{
printf("%d ", p[i]);
}
free(p);
p = NULL;
return 0;
}
输出结果:
realloc
realloc函数的出现让动态内存管理更加灵活。
有时我们会发现之前申请的空间太小了,有时又会觉得申请的空间过大了,因此我们会对内存的带下做灵活的调整。
cplusplus介绍如下:
1.realloc函数具有两个参数,第一个参数为要调整的动态内存地址,第二个参数为调整之后的新的大小(单位是字节)
2…若开辟空间成功,则返回一个指向调整之后的起始位置的指针,若开辟空间失败,则返回一个空指针。
realloc使用方式
这里仍以上面的代码为例:我们原本打印了1 ~ 10,如果我想打印1~15,并且不创建一个新的动态内存,该怎么做呢?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(40);
int i = 0;
for (i = 0; i < 10; i++)
{
p[i] = i + 1;
}
//从此修改
int* ptr = realloc(p, 60); //添加了5个int型,则扩容至60个字节
for (i = 10; i < 15; i++)
{
ptr[i] = i + 1;
}
for (i = 0; i < 15; i++)
{
printf("%d ", ptr[i]);
}
free(p);
p = NULL;
return 0;
}
打印结果:
至此,本章内容就结束了,这里需要提一下的是:因为本章重点是如何实现动态内存开辟,所以如果开辟内存失败的情况我就没有判断,以免初学者眼花缭乱。对于开辟动态内存时的注意事项,我将写一篇博客单独讲解。
文末BB:对哪里有问题的朋友,可以在评论区留言,若哪里写的有问题,也欢迎朋友们在评论区指出,博主看到后会第一时间确定修改。最后,制作不易,如果对朋友们有帮助的话,希望能给点点赞和关注.