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语言之动态分配内存相关推荐

  1. c语言分配内存空间方法,C语言之动态分配内存空间

    动态分配内存 为什么需要动态分配内存: 1.存储的数据 需要延长生命周期 2.一个指针变量需要存储数据,变量本身只能存地址,不能存数据,需要分配内存空间来存储数据 #include #include ...

  2. c语言链表动态分配内存,链表的C语言实现(含动态内存分配)

    转自:http://blog.csdn.net/21aspnet/article/details/146968 链表的C语言实现(含动态内存分配) 上 链表的C语言实现之动态内存分配 一.为什么用动态 ...

  3. C语言malloc动态分配内存分配失败怎么办?exit(OVERFLOW);(include <cstdlib>)

    如:(见<大话数据结构>147页) QueuePtr s = (QueuePtr)malloc(sizeof(QNode)); if(!s){exit(OVERFLOW); } exit为 ...

  4. c语言增加动态分配的存储空间吗,C语言 关于内存动态分配问题

    全局变量:分配到 内存的静态区. 局部变量(非静态):分配到 内存的动态区.在存储区中称为栈(stack) 临时数据(C允许内存动态分配区域):存放在自由空间区,称为堆区(heap) 内存动态分配 得 ...

  5. c语言 什么时候需要malloc动态分配内存?

    转自https://www.cnblogs.com/tomato0906/articles/7711737.html 我讲解一下c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么 ...

  6. c语言 什么时候需要动态分配内存?

    我讲解一下c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢?系统难道不是会自动分配内存吗?? 既然有人会问这样的问题,那么我在这里好好的讲解一下吧 ...

  7. 什么时候需要动态分配内存?

    我讲解一下c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢?系统难道不是会自动分配内存吗??既然有人会问这样的问题,那么我在这里好好的讲解一下吧! ...

  8. 【C语言】动态内存分配

    [C语言]动态内存分配 文章目录 [C语言]动态内存分配 一.malloc 与free函数 二.calloc 三.realloc 四.常见的动态内存的错误 本期,我们将讲解malloc.calloc. ...

  9. (篇二)C语言动态分配内存、计算π的值

    文章目录 一.动态分配内存 二.猴子吃桃问题 三.两种计算π的值 四.计算指定年月有几天 本篇是接着分享一些有趣的C语言实例,其实学习C语言这类结构化语言是非常锻炼逻辑思维的,也可以让我们对编程语言有 ...

最新文章

  1. Spring Cloud JWT文件生成
  2. LeetCode Kth Smallest Element in a BST(中序遍历)
  3. 最高一万星!GitHub 标星最多的 40 篇 ICLR2020 计算机视觉论文合集,附打包下载
  4. Hadoop Yarn任务优先级(作业优先级、应用优先级)设置
  5. JDBC连接MySQL数据库及示例
  6. 微软OTech第二次会议(广州站)
  7. ASP.NET Core 3.0 项目开始“瘦身”
  8. 春运期间长江海事局开辟四类运输“绿色通道”
  9. Linux 根据服务名字找安装路径
  10. OpenVINO DL workbench的docker安装
  11. 国产操作系统(1)UOS安装QT
  12. 合格的程序员精通c语言吗,只精通一门C语言的人算不算程序员?
  13. Web Worker使用教程
  14. 语音验证码接口(JSP)语言
  15. 【TP5】安装Guzzle并简单使用
  16. php微信摇一摇,申请开通微信摇一摇
  17. 小组取什么名字好_寓意兴旺的公司名字取什么名字好
  18. sql server出生年月减去退休年月 计算年龄
  19. 【ESP32_8266_BT篇(三)】GATTATT协议规范
  20. python中ipo模型有,python ipo模型是指什么?-Python教程

热门文章

  1. 华为OD机试真题 Java 实现【完美走位】【2022.11 Q4】
  2. 2020010909
  3. 【首次起用黑人模特的Prada】
  4. 数据库高并发的解决方案
  5. 【acwing】166. 数独****(DFS)
  6. java hypot_Java StrictMath hypot()方法
  7. 使用XMind打开.mmap文件不显示问题
  8. 仿热血江湖游戏类46地面物品类
  9. 手机app视频平台开发怎么做
  10. 窗口函数查询优化案例