【C语言】动态内存的管理
前言
本篇博客就来探讨一下动态内存,说到内存,我们以前开辟空间大小都是固定的,不能调整这个空间大小,于是就有动态内存,可以让我们自己选择开辟多少空间,更加方便,让我们一起来看看动态内存的有关知识吧
个人主页:小张同学zkf
若有问题 评论区见
感兴趣就关注一下吧
目录
1.什么是动态内存
2. malloc和free
2.1 malloc
2.2 free
3. calloc和realloc
3.1 calloc
3.2 realloc
4. 常见的动态内存的错误
4.1 对NULL指针的解引用操作
4.2 对动态开辟空间的越界访问
4.3 对非动态开辟内存使用free释放
4.4 使用free释放一块动态开辟内存的一部分
4.5 对同一块动态内存多次释放
4.6 动态开辟内存忘记释放(内存泄漏)
5. 动态内存经典笔试题分析
5.1 题目1:
5.2 题目2:
5.3 题目3:
5.4 题目4:
6. 柔性数组
6.1 柔性数组的特点:
6.2 柔性数组的使用
6.3 柔性数组的优势
1.什么是动态内存
首先我们要搞清楚什么是动态内存的分配?
平常我们定义的数组,都是在栈区分配的空间,都是分配的空间都是固定的大小
这种分配固定大小的内存分配方法称之为静态内存分配
与静态内存相对的,就是可以控制内存的分配的动态内存分配
注意:这里动态内存分配的空间是在堆区申请的,不是在栈区申请的
我们再来看看内存各个空间都是什么
1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内 存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。 2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。 3. 数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。 4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。2. malloc和free
我们来了解下动态内存的函数,对了以下所有函数的头文件都是
2.1 malloc
C语言提供了一个动态内存开辟的函数:
void * malloc ( size_t size);这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
注意:
• 如果开辟成功,则返回一个指向开辟好空间的指针。 • 如果开辟失败,则返回一个 NULL 指针,因此malloc的返回值一定要做检查。 • 返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。 • 如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器2.2 free
C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的,函数原型如下: void free ( void * ptr); free函数用来释放动态开辟的内存。 • 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。 • 如果参数 ptr 是NULL指针,则函数什么事都不做。
#include
#include
int main()
{
int num = 0;
scanf("%d", &num);
int arr[num] = {0};
int* ptr = NULL;
ptr = (int*)malloc(num*sizeof(int));
if(NULL != ptr)//判断ptr指针是否为空
{
int i = 0;
for(i=0; ii =
100
;
p->p_a = (
int
*)
malloc
(p->i*
sizeof
(
int
));
//
业务处理
for
(i=
0
; ip_a[i] = i;
}
//
释放空间
free
(p->p_a);
p->p_a =
NULL
;
free
(p);
p =
NULL
;
return
0
;
}
上述代码
1
和代码
2
可以完成同样的功能,但是方法
1
的实现有两个好处:
第一个好处是:方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
第二个好处是:这样有利于访问速度.
连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)
结束语
动态内存的存储算是总结完了,动态内存我个人感觉也算是比较难,有点绕,可以多来回看看这篇博客,有什么问题跟我讨论,下一篇博客见
OK感谢观看!!!






