💓博主csdn个人主页:小小unicorn💓
⏩专栏分类:c语言⏪
🚚代码仓库:小小unicorn的学习足迹🚚
🌹🌹🌹关注我带你学习编程知识
1.为什么存在动态内存分配
先思考一下,按照我们现有的知识,内存开辟方式有两种
int val=20; char arr[10]={0};
但是上面开辟空间的方式有两个特点
1.空间开辟大小是固定的
2.数组在声明的时候,必须指定数组的大小,它所需的内存在编译时分配
往往对内存分配不能局限,那么就可以试试动态内存分批
2.动态内存函数的介绍
2.1 malloc和free函数
c语言提供了一个动态内存开辟的函数
void*malloc(size_t size);
这个函数向内存中申请一个连续可用的空间,并返回指向这块空间的指针。
代码示例
#include<stdio.h> #include<stdlib.h> int main() { int* p = (int*)malloc(40); if (p == NULL) { perror("malloc"); return 1; } //开辟成功 int i = 0; for (i = 0; i < 10; i++) { printf("%d\n", *(p + i)); } return 0; }
运行结果如下:
让我们通过画图来简单分析一下:
在内存中,系统会划分为三个区域。分别为栈区,堆区以及静态区。
在堆区里,我们实现动态内存开辟。值得注意的是:malloc申请到空间后,直接返回这块空间的起始地址,不会初始化空间的内容。
当malloc申请的内存空间,当程序退出时,还给操作系统,当程序不退出时,动态申请的内存,不会主动释放,因此我们需要使用free函数来进行释放
free函数原型如下:
void free(void*ptr);
示例:
用free 函数来释放内存要注意一点,free只能释放动态开辟的空间。
下面这个例子就是错误的,
2.1 calloc函数
函数原型
void*calloc(size_t num,size_t size)
calloc函数与malloc函数不一样的地方就是,calloc函数在开辟空间会进行初始化操作,会在返回地址之前把申请的空间的每个字节初始化为0
代码示例:
int main() { int* p = (int*)calloc(INT_MAX, sizeof(int)); if (p == NULL) { perror("calloc"); return 1; } //打印数据 int i = 0; for (i = 0; i < 10; i++) { printf("%d", p[i]); } //释放 free(p); p = NULL; return 0; }
总结一下:如果我们对申请的内存空间的内容要求初始化的时候,那么我们可以很方便的使用calloc函数来完成任务
2.1 realloc函数
函数原型:
void*relloc(void*ptr,size_t siuze);
ptr是要调整的内存地址
size是调整之后新大小
返回值为调整之后的内存起始位置
代码示例:
int main() { int* p = (int*)malloc(40); if (p == NULL) { perror("malloc"); return 1; } //初始化为1-10 int i = 0; for (i = 0; i < 10; i++) { p[i] = i + 1; } //增加一些空间 int* ptr = (int*)realloc(p, 80); if (ptr != NULL) { p = ptr; ptr = NULL; } else { perror("realloc"); return 1; } //打印数据 for (i = 0; i < 20; i++) { printf("%d\n",p[i]); } //释放 free(p); p = NULL; return 0; }
运行结果:
这里呢,需要用画图来分析一下realloc是如何来开辟空间的
具体分两种情况:
情况1:
情况2:
3.总结
通过本篇文章,我们了解并学习了什么是动态内存,以及通过学习malloc,calloc和realloc函数来开辟内存,用free函数来释放内存。
补充一下
C/C++程序内存分配的几个区域:
- 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结
束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是
分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返
回地址等。 - 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分
配方式类似于链表。 - 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
- 代码段:存放函数体(类成员函数和全局函数)的二进制代码。
本篇文章到这就结束了,希望对大家有所帮助!