之前我们有掌握单个元素和连续数组的创建,同样也是内存开辟方式,但对于空间的需求,上述的情况不能够全部满足,有时我们需要的空间大小在程序运行时才能知道,那数组的编译时开辟空间的方式就不能满足这种情况了。这时就需要使用动态内存分配了。
本篇文章将解读C语言中动态内存管理与函数。通过简洁高效的代码,为读者提供一个清晰明了的讲解,让我们开始吧!!
之前我们已经掌握过的内存开辟方式:
int a = 0;//在内存开辟四个字节的空间
int arr[10] = {0};//在内存中开辟一块连续的整型(40字节)空间
上述内存开辟方式有两种特点:
但对于空间的需求,上述的情况不能够全部满足,有时我们需要的空间大小在程序运行时才能知道,那数组的编译时开辟空间的方式就不能满足这种情况了TT。这时就只能使用动态内存分配了。
前提!!在使用这类函数前都要引用头文件#include
c语言提供了一个动态内存开辟的函数:
该malloc函数会向内存申请一块连续可用的空间,并返回指向该空间的指针。返回类型是void*,所以malloc函数并不知道自己开辟内存的具体类型,由具体使用时操作者来决定。
参数size如果是0,malloc的行为是未定义的,取决于编译器。
要注意!!!这类动态内存函数是有可能开辟失败的:
如果开辟成功,函数就返回指向该开辟的内存空间的指针。
如果开辟失败,函数就返回空指针NULL。
因此函数返回值 一定! 要进行检查。
那这种特殊内存该如何释放呢?
1.free 主动释放
2.程序退出后,由操作系统回收。
因为该类函数比较特殊,C语言还提供了另一个函数free,来专门做动态内存的释放和回收的,函数定义如下:
free函数用来释放动态开辟的内存。
要注意以下几点:
如果参数ptr不是动态开辟的内存,那free函数的行为是未被定义的。
如果参数ptr内容为NULL,那函数free什么都不做。
函数free完之后原指针ptr就变成了野指针,需要将其赋值NULL
free函数都是和动态内存函数同时使用。
进行简单了解之后我们现在来实际操作一下。
举个栗子:我们运用动态内存函数malloc打印10个数
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
//运用动态内存函数malloc打印10个数
int main()
{
int* p = (int*)malloc(10 * sizeof(int));//强制类型转换成int*方便操作
int i = 0;
if(p != NULL)//判断p指针是否为空
{
for (i = 0; i < 10; i++)
{
p[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", p[i]);
}
free(p);//释放指针p,即释放内存
p = NULL;//将指针置为空
}
printf("\n\n别忘了点赞三连支持欧o(>ω< )o!!!\n");
printf("(深情)\n");
return 0;
}
我们也可以看看p指针在free前后会有什么变化:
可以看到虽然p指针free后将内存还给了操作空间,我们无法操作该指针指向的空间,但是p指针里存放的还有刚刚开辟的内存地址,为了防止出现调用野指针报错,我们就必须将其赋值为NULL。
C语言还提供了叫calloc,它和malloc很像,原型如下:
该函数的功能是为num个大小为size的元素开辟一整块空间,并把空间内每个字节都初始化成0(和malloc唯一的区别)。
举个例子:
#include
#include
int main()
{
int* p = (int*)calloc(10, sizeof(int));
if (NULL != p)
{
//进行一个空间的使用(省略)
}
free(p);
p = NULL;
return 0;
}
看看开辟的内存:
有时我们会发现过去申请的空间有点太小了,有时我们又觉得申请的空间过大了,为了合理利用内存,我们需要能够对动态内存进行一个灵活的调整。realloc函数就可以做到对动态开辟内存大小进行调整。
函数原型如下:
ptr是要调整的内存地址
size是调整之后的新大小
返回值为调整之后的内存起始位置
我们在使用realloc时会遇到两种情况:
情况1:目标调整空间后有足够可用内存。
好了以上就是本篇“【C语言】动态内存管理与函数解读”博客的全部内容啦,感谢各位的阅读=v=,如有不足之处欢迎在评论区指出哦!!
觉得可以的话别忘了点赞三连支持一下欧!拜托啦这对我真的很重要o(>ω< )o!!!