C语言之动态分配内存
1. malloc()函数和free()函数
首先,我们应该知道,所有的程序都必须留出足够的内存空间来存储所使用的数据,所以我们经常会预先给程序开辟好内存空间,然后进行操作,但其实还有一种选择,能够让内存分配自动进行下去。
对于传统数组,会遇到这样的问题:
int arr[5] ;
对这个数组我们在定义的时候必须给提前开辟好空间,并且在程序执行的过程中,这个开辟的内存空间是一直存在的,除非等到这个函数执行完毕,才会将空间释放。还有一个问题就是这个数组在程序中无法被修改。
这些问题给我们造成了一些使用上的不方便,所以,C中提供了malloc()函数。
关于malloc()函数,这个函数它接受一个参数:就是所需的内存的字节数。然后malloc()找到可用内存中那一个大小适合的块。在这个过程中,malloc()可以来返回那块内存第一个字节的地址。所以,也就意味了我们可以使用指针来操作。malloc()可以用来返回数组指针、结构指针等等,所以我们需要把返回值的类型指派为适当的类型。当malloc()找不到所需的空间时,它将返回空指针。
例:
double *p;
p=(double*)malloc(30*sizeof(double));
在这个程序中,首先开辟了30个double类型的空间,然后把p指向这个空间的位置。在这里的指针是指向第一个double值。并不是我们全部开辟的30个double的空间。这就和数组一样,指向数组的指针式指向数组首元素的地址,并不是整个数组的元素。所以,在这里我们的操作也和数组是一样的,
p[0]就是第一个元素,p[2]就是第二个元素。
至此,我们就可以掌握到一种声明动态数组的方法。
int arr[n];
p=(int *)malloc(n*sizeof(int));
//我们在这里使用的时候要元素个数乘类型字节长度,这样就达到了动态开辟内存空间。
当我们使用malloc()开辟完内存空间以后,我们所要考虑的就是释放内存空间,在这里,C给我们提供了free()函数。free()的参数就是malloc()函数所返回的地址,释放先前malloc()函数所开辟的空间。
例:
对于上面我们所开辟的空间进行释放,那么我们就可以这样
free(p);
程序还调用了exit()函数,这个函数是在内存分配失败时结束程序。
程序例子:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<malloc.h>//malloc()函数被包含在malloc.h里面
#include<stdlib.h>
int main(void)
{char*a = NULL;//声明一个指向a的char*类型的指针a = (char*)malloc(100 * sizeof(char));//使用malloc分配内存的首地址,然后赋值给aif (!a)//如果malloc失败,可以得到一些log{perror("malloc");return-1;}sprintf(a, "%s", "HelloWorld\n");//"HelloWorld\n"写入a指向的地址printf("%s\n", a);//输出用户输入的数据free(a);//释放掉使用的内存地址system("pause");return 0;//例2有无内存泄露?
}
这个程序主要用来检测malloc返回值条件有误。
在这里我们需要注意,在C中,类型指派(char *)是可选的,但是在C++中这个是必须有的,所以使用类型指派将使把C程序移植到C++更容易。
使用动态数组,主要是为了获得程序的灵活性。我们嗯可以需要多少个元素就让数组开辟多少个,。不需要浪费空间
2.free()的重要性
在我们使用malloc()函数的时候,分配的内存是会增加的,当我们使用free()函数时,可以释放内存。
例如:
...int main()
{double glad[2000];int i;...for(i=0;i<1000;i++)gobble(glad,2000);...
}
void gobble(double arr[],int n)
{double *temp=(double *)malloc(n*sizeof(double));...
}
在这个程序当中我们使用了malloc()函数,但是我们没有使用free()函数,在这个程序中,我们首先进入gobble()函数,穿件了指针temp,并且使用了malloc()函数。但是除了gobble()函数之后,指针作为一个变量消失了,但是所开辟的内存是依然存在的,我们依然开辟了16000个字节的内存。但是我们却无法去访问这些内存,因为他们的地址不见了。因为没有调用free()函数,这段内存也不能再此使用了。
这样依次循环,总共执行for循环1000次,最终导致了程序总共16000000个字节的内存无法使用,这样,内存肯定已经溢出了。这样就会出现我们所说的程序泄漏问题,而free()函数,正好解决了这种的问题。
3.calloc()函数和realloc()函数
接下来,我们在认识两个关于内存分配的函数。calloc()函数和realloc()函数。
calloc()函数与malloc()函数有相同之处,也有相似之处。
例:
short *p;
newmem=(short *)calloc(1000,sizeof(short));
通过这个例子,我们可以知道calloc()函数有两个参数,并且这两个函数都是size_t类型(unsigned int类型)的数。第一个参数在这里所说的是所需要开辟的内存单元数量,第二个参数是每个单元的字节的大小。
void *calloc(size_t ,size_t);
calloc()函数还有一个特性,它将块中的全部位都置为0。这也是calloc()函数和malloc()函数的区别,calloc()函数和malloc()函数的另外一个区别是他们请求内存数量的方式不一样。当然,free()函数也可以来释放calloc()函数分配的内存。
realloc()函数用来修改一个原先已经分配的内存的大小。使用这个函数,你可以让一块内存增大还是缩小。当扩大时,这块内存原先的内容会依然保留,新增加的添加到原先的后面。缩小时,该内存的尾部部分内存去掉,剩余保留。
注意:对于realloc()函数,如果原先的内存无法修改,这时候realloc()函数再会分配一块内存,并且把原先那块内存的内容复制到上面去。所以,使用了realloc函数以后,你这时候在使用的就该是realloc函数返回的新指针了。当realloc函数的第一个参数是NULL时,这时候我们可以把它当作是malloc()函数。
写博客已经半个月了,感觉问题还是很多,希望大家多多指点。
C语言之动态分配内存相关推荐
- c语言分配内存空间方法,C语言之动态分配内存空间
动态分配内存 为什么需要动态分配内存: 1.存储的数据 需要延长生命周期 2.一个指针变量需要存储数据,变量本身只能存地址,不能存数据,需要分配内存空间来存储数据 #include #include ...
- c语言链表动态分配内存,链表的C语言实现(含动态内存分配)
转自:http://blog.csdn.net/21aspnet/article/details/146968 链表的C语言实现(含动态内存分配) 上 链表的C语言实现之动态内存分配 一.为什么用动态 ...
- C语言malloc动态分配内存分配失败怎么办?exit(OVERFLOW);(include <cstdlib>)
如:(见<大话数据结构>147页) QueuePtr s = (QueuePtr)malloc(sizeof(QNode)); if(!s){exit(OVERFLOW); } exit为 ...
- c语言增加动态分配的存储空间吗,C语言 关于内存动态分配问题
全局变量:分配到 内存的静态区. 局部变量(非静态):分配到 内存的动态区.在存储区中称为栈(stack) 临时数据(C允许内存动态分配区域):存放在自由空间区,称为堆区(heap) 内存动态分配 得 ...
- c语言 什么时候需要malloc动态分配内存?
转自https://www.cnblogs.com/tomato0906/articles/7711737.html 我讲解一下c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么 ...
- c语言 什么时候需要动态分配内存?
我讲解一下c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢?系统难道不是会自动分配内存吗?? 既然有人会问这样的问题,那么我在这里好好的讲解一下吧 ...
- 什么时候需要动态分配内存?
我讲解一下c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢?系统难道不是会自动分配内存吗??既然有人会问这样的问题,那么我在这里好好的讲解一下吧! ...
- 【C语言】动态内存分配
[C语言]动态内存分配 文章目录 [C语言]动态内存分配 一.malloc 与free函数 二.calloc 三.realloc 四.常见的动态内存的错误 本期,我们将讲解malloc.calloc. ...
- (篇二)C语言动态分配内存、计算π的值
文章目录 一.动态分配内存 二.猴子吃桃问题 三.两种计算π的值 四.计算指定年月有几天 本篇是接着分享一些有趣的C语言实例,其实学习C语言这类结构化语言是非常锻炼逻辑思维的,也可以让我们对编程语言有 ...
最新文章
- Spring Cloud JWT文件生成
- LeetCode Kth Smallest Element in a BST(中序遍历)
- 最高一万星!GitHub 标星最多的 40 篇 ICLR2020 计算机视觉论文合集,附打包下载
- Hadoop Yarn任务优先级(作业优先级、应用优先级)设置
- JDBC连接MySQL数据库及示例
- 微软OTech第二次会议(广州站)
- ASP.NET Core 3.0 项目开始“瘦身”
- 春运期间长江海事局开辟四类运输“绿色通道”
- Linux 根据服务名字找安装路径
- OpenVINO DL workbench的docker安装
- 国产操作系统(1)UOS安装QT
- 合格的程序员精通c语言吗,只精通一门C语言的人算不算程序员?
- Web Worker使用教程
- 语音验证码接口(JSP)语言
- 【TP5】安装Guzzle并简单使用
- php微信摇一摇,申请开通微信摇一摇
- 小组取什么名字好_寓意兴旺的公司名字取什么名字好
- sql server出生年月减去退休年月 计算年龄
- 【ESP32_8266_BT篇(三)】GATTATT协议规范
- python中ipo模型有,python ipo模型是指什么?-Python教程