hello hello,本篇文章将讲解关于C语言动态内存管理的知识,动态内存管理是一个很重要的知识点,希望这篇文章能让各位uu们对知识的认识和理解更深一步。
目录
为什么有动态内存分配
动态内存分配函数
1.malloc
2.free
3.calloc
4.realloc
常见的动态内存错误
柔性数组
一、什么有动态内存分配
在我们编程的时候,往往会涉及到开辟空间的问题,像定义数组时我们会设定数组的大小,也就是我们向内存空间申请的空间,但是这块空间的大小是固定死的,如果存入数据不多就会造成空间浪费,数据过多会放不下,这里就会有uu说,那我在知道到底要多大空间之后再定义数组就好啦,但是在变成解决问题时,这些信息不一定是能准确地知道的,而且在编程过程中,所需的内存空间可能是会发生变化的,所以这个时候,动态内存分配的作用就凸现出来了。
使用动态内存分配可以随时向内存申请所需要的大小,可以按需控制空间大小,灵活性更高,空间利用率实现最大化(现阶段)。
二、动态内存分配函数
使用动态分配函数向内存申请的空间是位于堆区的
我们常用的内存区域的分块如下图所示
1. malloc
函数原型:void *malloc( size_t size );
函数功能:向内存的堆区申请指定字节大小的空间
- size表示要开辟空间的字节数
- void* 表示返回类型为空指针
- 如果申请空间成功,将会返回指向这块空间的首地址,如果申请空间失败,将会返回NULL(空指针进行解引用是非法的,我们在使用的时候会对返回值进行强制转换)
- 基于上述,我们在 *** 作返回的指针时需要先判断其是否为空
- size=0这种情况是标准未定义的,结果取决于编译器
2. free
函数原型:void free( void *memblock );
函数功能:将动态开辟的内存释放,还给 *** 作系统
- membolck表示使用动态开辟函数申请的空间的地址指针
- void表示free函数没有返回值
- free一般都是与动态开辟函数malloc、calloc、realloc配套使用
- 要释放动态开辟的空间,那就一定得得到这块空间的首地址,所以使用函数开辟空间得到得指针不能随意改动
- free之后,这块空间还给了 *** 作系统,但是指针指向的地址没有发生改变,也就是说,此时原来指针成为了野指针,需要将其置空
- 如果动态开辟的内存不使用free进行释放,会有内存泄漏的风险
- 如果传入的指针为NULL,那么free啥都不干,如果不是指向动态内存的指针,这种行为是标准未定义的
3. calloc
函数原型:void *calloc( size_t num, size_t size );
函数功能:向内存的堆区申请指定字节大小的空间,并将该块空间初始化为0
- num表示一个数据的个数
- size表示一个数据类型所占字节大小
- void*表示函数返回类型为空指针(注意事项同malloc)
- calloc的功能约等于malloc加上memset
- 与malloc的相同点:都是用来开辟动态内存空间的
- 区别:两个函数的参数不同
- 本质上的区别不大,看个人需求选择使用
4. realloc
函数原型:void *realloc( void *memblock, size_t size );
函数功能:调整所开辟空间的大小
- memblock表示需要调整的空间的起始地址
- size表示调整后整个空间所占字节数
- void*表示函数返回值是空指针(注意事项与malloc相同)
- realloc扩容存在两种情况:如果要扩大空间后面的空间满足需要,可以直接在原地进行扩容,那么就直接返回原来的起始地址
- 如果要扩大空间后面的空间不能满足需要,那么realloc会在内存的堆区寻找一块足够大的空间开辟,并且将原来内存空间的内容拷贝过来,释放掉原来的空间,并返回当前空间的首地址
- 将空间缩小就不存在你上述情况了
三、常见的动态内存错误
1. 对NULL的解引用 *** 作;(在使用函数进行内存开辟后要进行判空之后再使用)
2. 对动态开辟空间的越界访问;(对空间进行访问时,自己要想明白内存的边界)
3. 对非动态开辟的空间使用free释放空间;
4. 使用free释放一部分动态开辟的空间;(使用函数开辟空间得到的指针不能随意改动)
5. 对同一块动态空间进行多次释放;
6. 忘记释放动态开辟的内存空间。
切记,动态开辟的内存空间一定要释放,且正确地释放
四、柔性数组
C99标准引入了柔性数组的概念,什么是柔性数组呢?
结构体变量最后一个成员是一个未指定大小的数组,这个数组就是柔性数组
struct S1
{
int i;
int arr[];//这就是柔性数组
};
柔性数组的特点:
- 在计算含有柔性数组的结构体大小的时候,不计算柔性数组的大小
- 柔性数组前面至少有一个其他成员变量
- 要使用malloc进行动态内存分配,且申请的空间大小要大于结构体的大小,后面剩余的空间就全部是柔性数组的了
- 如果空间不够用,可以使用realloc扩容
- 只能放在结构体的最后才叫柔性数组
以上就是动态内存的全部分享了,欢迎各位uu指正~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)