【C语言】动态内存分配
【C语言】动态内存分配
文章目录
- 【C语言】动态内存分配
- 一、malloc 与free函数
- 二、calloc
- 三、realloc
- 四、常见的动态内存的错误
本期,我们将讲解malloc、calloc、realloc以及free函数。
这是个动态内存分配函数的头文件都是 <stdlib.h>。
c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢?
首先让我们熟悉一下计算机的内存吧!在计算机的系统中大致有这四个内存区域:
1)栈:在栈里面储存一些我们定义的局部变量以及形参(形式参数);
2)字符常量区:主要是储存一些字符常量,比如:char *p=”hello world”;其中”hello world”就储存在字符常量区里面;
3)全局区:在全局区里储存一些全局变量和静态变量;
- 堆:堆主要是通过动态分配的储存空间,也就是我们接下需要讲的动态分配内存空间。
静态内存和动态内存的比较:
- 静态内存是有系统自动分配,由系统自动释放。 静态内存是在栈分配的。(例如:函数里的局部变量)
- 动态内存是由程序员手动分配,手动释放。 动态内存是在堆分配的。(例如:用C语言写链表时,需要自己对Node结点分配内存空间)
一、malloc 与free函数
void* **malloc( size_t ** size);
返回类型: void*,也就是说这个函数的可以返回所有类型的指针形式。只需要在开辟空间的时候进行强制类型转换一下即可。
函数参数:size_t size, 这个参数就是告诉这个函数,你需要开辟多少个字节的内存空间。
void free(void* memblock) ;
没有返回参数。
函数参数:void* memblock, free函数可以接收来自所有类型指针的 动态分配 的 内存空间。
一切以栗子来描述吧:
#include <stdlib.h>
#include <stdio.h>
int main()
{//开辟10个int类型的空间int* arr = (int*)malloc(10 * sizeof(int)); //切记这里给的大小,是10 * int(4个字节)int i = 0;if (arr == NULL){perror("malloc"); //有可能,malloc开辟空间失败,则malloc会返回NULLreturn 1;}for (i = 0; i < 10; i++)*(arr + i) = i; //放入数据 0 …… 9for (i = 0; i < 10; i++)printf("%d ",*(arr + i));//记得释放所开辟的空间free(arr); return 0;
}
二、calloc
void* calloc (size_t num, size_t** size );
返回类型:与malloc函数是一样的,就不在多说了。
函数参数:size_t num, 需要开辟多少个元素的空间。
size_ size, 每一个元素,所占用的内存空间是多少个字节。
注:与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
栗子:
#include <stdlib.h>
#include <stdio.h>int main()
{//还是申请10个int类型的内存空间int* arr = (int*)calloc(10, sizeof(int));if (arr == NULL){perror("calloc"); //calloc开辟空间的话,会返回NULLreturn 1;}//不做赋值运算,直接输出刚开辟的空间,看是否是已经初始化为0了int i = 0;for (i = 0; i < 10; i++)printf("%d ",*(arr + i));//记得释放空间free(arr);return 0;
}
三、realloc
void* **realloc(*void memblock, size_t size);
作用: Reallocate memory blocks.(重新分配内存块)
memblock是需要调整的内存地址
size调整之后新大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础_上,还会将原来内存中的数据移动到新的空间。
realloc在调整内存空间的是存在两种情况:
情况1 :原有空间之后有足够大的空间
假设我还想为“红色框内的内存空间,扩大一倍,并且在这块空间的后面,是有足够的空间。所有realloc函数会在这紧挨这红色框后面直接开辟空间。并且返回的还是红色框的首元素地址。
情况2: 原有空间之后没有足够大的空间
此时,如果我还想为红色框的内存空间进行扩大,此时红色框后面紧挨着的空间已经被其他程序所占用了,此时想开辟空间的话,只能将现在这块空间先释放掉(realloc会自动释放),再去其他大一点的地方进行开辟空间。
如图:
注:realloc函数,有一个很值得注意的地方,看如下代码:
int main()
{int* arr = (int*)malloc(5 * sizeof(int)); //先开辟5个int类型的空间if (arr == NULL)return 1;//此时,我觉得malloc开辟的空间小了,我想增加arr = (int*) realloc(arr, 10);free(arr);return 0;
}
大家觉得,这段代码,有什么弊端?
分析:
在第8行,realloc函数,去调整arr的空间。他是先查看arr后面的内存空间是否够用,如果不够用的话,会去寻找其他大一点的地方去开辟空间。假设此时我的内存已经满了,此时realloc返回的是NULL。
也就是说,我本来想增容,结果没增成功,还把以前空间里的数据弄丢了。
所以在使用realloc函数时,先使用一个临时变量进行保存一下,如果返回不是NULL,我们在把返回的内存地址赋值给arr即可。
如下:
int main()
{int* arr = (int*)malloc(5 * sizeof(int)); //先开辟5个int类型的空间if (arr == NULL)return 1;//此时,我觉得malloc开辟的空间小了,我想增加int* tmp = NULL;tmp = (int*) realloc(arr, 10);if (tmp != NULL)arr = tmp;free(arr);return 0;
}
四、常见的动态内存的错误
对NULL进行解引用操作
int main() {int* arr = (int*)malloc(10 * sizeof(int));*arr = 10; //没有对arr进行NULL的判断free(arr);return 0; }
对非动态内存分配的空间进行free释放
int main() {int a = 10;int* pa = &a;free(pa); //pa指针,并不是malloc等函数开辟的空间,不能使用free释放,系统会自动回收的return 0; }
使用free函数释放一块动态分配空间的一部分
int main() {int* arr = (int*)malloc(10 * sizeof(int));if (arr == NULL)return 1;arr++; //此时,arr向后跳了4个字节free(arr); //现在再去释放空间,最前面的4个字节的空间就没有释放到,会报错return 0; }
对同一块内存空间进行多次释放
int main() {int* arr = (int*)malloc(10 * sizeof(int));if (arr == NULL)return 1;free(arr);free(arr); //重复释放了return 0; }
动态开辟的空间忘记释放(内存泄漏)
int main() {int* arr = (int*)malloc(10 * sizeof(int));if (arr == NULL)return 1;//没有释放空间,会造成内存泄漏//造成内存泄漏,有很多原因,例如,在调用其他函数时,想传回到本函数,指针没用正确,导致开辟的空间没有传回来等等return 0; }
注: 动态开辟的内存空间,切记 一定要释放。不然后果很严重的!!!
本期更新就完啦!!!我们下期见啦
main()
{
int* arr = (int*)malloc(10 * sizeof(int));
if (arr == NULL)
return 1;
//没有释放空间,会造成内存泄漏//造成内存泄漏,有很多原因,例如,在调用其他函数时,想传回到本函数,指针没用正确,导致开辟的空间没有传回来等等return 0;
}
注: 动态开辟的内存空间,切记 一定要释放。不然后果很严重的!!!本期更新就完啦!!!我们下期见啦
【C语言】动态内存分配相关推荐
- c语言动态内存分配数组,【C】动态内存分配
## 动态内存分配的意义 C语言中的一切操作都是基于内存的 变量和数组都是内存的别名 内存分配由编译器在编译期间决定 定义数组的时候必须指定数组长度 数组长度是在编译期就必须确定的需求: 程序在运行过 ...
- linux 在指定区域分配内存 c语言,C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存...
一.malloc/free概述 malloc是在C语言中用于在程序运行时在堆中进行动态内存分配的库函数.free是进行内存释放的库函数. 1.函数原型 #include void *malloc( s ...
- C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存
最新个人博客 shankusu.me 以下内容转载或参考或引用自 https://blog.csdn.net/zxx910509/article/details/62881131 一.malloc/f ...
- C语言动态内存分配详解
文章目录 前言 一.为什么存在动态内存分配 1.已掌握的内存开辟方式 2.上述开辟空间方式的特点 3.为什么存在动态内存分配 二.动态内存函数的介绍 1.malloc 2.free 3.calloc ...
- C语言:动态内存分配+经典面试题
前言: 通常,我们在栈空间开辟的内存都是固定的,这是十分不方便使用的.为了更加灵活的分配和使用内存,我们要学习C语言中一些常用的与内存分配相关联的函数.顺便,我们会补充数组中柔性数组的知识. 内存分区 ...
- 浅谈C语言动态内存分配及柔性数组
文章目录 前言 1.动态内存的简单介绍 1.动态内存分配是什么? 2.为什么存在动态内存分配? 3.动态内存分配具体方法 1.动态内存函数 2.动态内存注意事项 2.经典面试题分析 3.C/C++程序 ...
- C语言动态内存分配函数
目录 1.malloc() 2.free() 3.calloc() 4.realloc() 5.小结 在C中我们开辟内存空间有两种方式 : 1.静态开辟内存 : 例如: int a; int b[10 ...
- C语言-动态内存分配总结
目录 1 malloc 2 calloc 区别联系 3 memset 4 realloc 1 malloc void *malloc( unsigned int num_bytes) 分配长度为num ...
- C语言——动态内存分配
内存分配函数: malloc函数--分配内存块,但是不对其进行初始化. calloc函数--分配内存块,并且对其进行初始化(清0). realloc函数--调整先前分配的内存块大小. 函数原型: vo ...
- 不允许指针指向不完整的类类型_8.7 C语言动态内存分配与指向它的指针变量
01什么是内存的动态分配 1.全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,这个存储区是一个"栈"的区域. 2.C语言允许建立内存 ...
最新文章
- 四则运算表达式求值(栈的应用)
- C语言指针、数组与sizeof运算符
- CodeForces 615C
- 【HTML+CSS网页设计与布局 从入门到精通】第4章
- elasticsearch-head后台运行
- 基于JSP的旅游信息管理系统(含论文)
- 服务器子接口配置的几种方式:子接口模式、vlan模式
- 微信小程序分享和转发朋友圈功能
- 5G组网-SANSA
- MySQL(4) 数据库增删改查SQL语句(整理集合大全)
- Word2010为图片批量插入题注
- 让人感到惊艳的5款数据可视化大屏产品
- 电气火灾监控系统在太焦铁路博爱站房项目的应用
- 《当时只道是寻常》——安意如——品纳兰容若《饮水词》
- Linux下驱动开发
- 蛙蛙推荐:如何编写高质量的python程序
- 网格设计版式设计_编辑版式,排除项和CSS网格
- input框前追加图片
- PPP over Ethernet(PPPoE)协议
- 国内云服务器,服务商优缺点分析
热门文章
- VirtualBox 上的windows XP启动时蓝屏
- 安卓源码,跑步打卡项目app源码
- php 数据库万能引擎类,ADODB PHP 数据库万能引擎类
- JEESNS V1.4 发布,JAVA 开源 SNS 社区系统
- 关于SNS社区与行业电子商务结合一些看法
- mysql inserted表_数据库inserted的搜索结果-阿里云开发者社区
- 美国网红python微博_Python有趣|微博网红大比拼
- vue 声明周期函数_Vue 生命周期详解
- HDLbits exercises 13(MORE CIRCUITS全部题)
- quicklook打开word文字显示不正常