【C语言】动态内存分配

文章目录

  • 【C语言】动态内存分配
    • 一、malloc 与free函数
    • 二、calloc
    • 三、realloc
    • 四、常见的动态内存的错误

本期,我们将讲解malloc、calloc、realloc以及free函数。

这是个动态内存分配函数的头文件都是 <stdlib.h>

c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢?

首先让我们熟悉一下计算机的内存吧!在计算机的系统中大致有这四个内存区域:

1)栈:在栈里面储存一些我们定义的局部变量以及形参(形式参数);

2)字符常量区:主要是储存一些字符常量,比如:char *p=”hello world”;其中”hello world”就储存在字符常量区里面;

3)全局区:在全局区里储存一些全局变量和静态变量;

  1. 堆:堆主要是通过动态分配的储存空间,也就是我们接下需要讲的动态分配内存空间。

静态内存和动态内存的比较:

  • 静态内存是有系统自动分配,由系统自动释放。 静态内存是在分配的。(例如:函数里的局部变量)
  • 动态内存是由程序员手动分配,手动释放。 动态内存是在分配的。(例如:用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语言】动态内存分配相关推荐

  1. c语言动态内存分配数组,【C】动态内存分配

    ## 动态内存分配的意义 C语言中的一切操作都是基于内存的 变量和数组都是内存的别名 内存分配由编译器在编译期间决定 定义数组的时候必须指定数组长度 数组长度是在编译期就必须确定的需求: 程序在运行过 ...

  2. linux 在指定区域分配内存 c语言,C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存...

    一.malloc/free概述 malloc是在C语言中用于在程序运行时在堆中进行动态内存分配的库函数.free是进行内存释放的库函数. 1.函数原型 #include void *malloc( s ...

  3. C语言动态内存分配:(一)malloc/free的实现及malloc实际分配/释放的内存

    最新个人博客 shankusu.me 以下内容转载或参考或引用自 https://blog.csdn.net/zxx910509/article/details/62881131 一.malloc/f ...

  4. C语言动态内存分配详解

    文章目录 前言 一.为什么存在动态内存分配 1.已掌握的内存开辟方式 2.上述开辟空间方式的特点 3.为什么存在动态内存分配 二.动态内存函数的介绍 1.malloc 2.free 3.calloc ...

  5. C语言:动态内存分配+经典面试题

    前言: 通常,我们在栈空间开辟的内存都是固定的,这是十分不方便使用的.为了更加灵活的分配和使用内存,我们要学习C语言中一些常用的与内存分配相关联的函数.顺便,我们会补充数组中柔性数组的知识. 内存分区 ...

  6. 浅谈C语言动态内存分配及柔性数组

    文章目录 前言 1.动态内存的简单介绍 1.动态内存分配是什么? 2.为什么存在动态内存分配? 3.动态内存分配具体方法 1.动态内存函数 2.动态内存注意事项 2.经典面试题分析 3.C/C++程序 ...

  7. C语言动态内存分配函数

    目录 1.malloc() 2.free() 3.calloc() 4.realloc() 5.小结 在C中我们开辟内存空间有两种方式 : 1.静态开辟内存 : 例如: int a; int b[10 ...

  8. C语言-动态内存分配总结

    目录 1 malloc 2 calloc 区别联系 3 memset 4 realloc 1 malloc void *malloc( unsigned int num_bytes) 分配长度为num ...

  9. C语言——动态内存分配

    内存分配函数: malloc函数--分配内存块,但是不对其进行初始化. calloc函数--分配内存块,并且对其进行初始化(清0). realloc函数--调整先前分配的内存块大小. 函数原型: vo ...

  10. 不允许指针指向不完整的类类型_8.7 C语言动态内存分配与指向它的指针变量

    01什么是内存的动态分配 1.全局变量是分配在内存中的静态存储区的,非静态的局部变量(包括形参)是分配在内存中的动态存储区的,这个存储区是一个"栈"的区域. 2.C语言允许建立内存 ...

最新文章

  1. 四则运算表达式求值(栈的应用)
  2. C语言指针、数组与sizeof运算符
  3. CodeForces 615C
  4. 【HTML+CSS网页设计与布局 从入门到精通】第4章
  5. elasticsearch-head后台运行
  6. 基于JSP的旅游信息管理系统(含论文)
  7. 服务器子接口配置的几种方式:子接口模式、vlan模式
  8. 微信小程序分享和转发朋友圈功能
  9. 5G组网-SANSA
  10. MySQL(4) 数据库增删改查SQL语句(整理集合大全)
  11. Word2010为图片批量插入题注
  12. 让人感到惊艳的5款数据可视化大屏产品
  13. 电气火灾监控系统在太焦铁路博爱站房项目的应用
  14. 《当时只道是寻常》——安意如——品纳兰容若《饮水词》
  15. Linux下驱动开发
  16. 蛙蛙推荐:如何编写高质量的python程序
  17. 网格设计版式设计_编辑版式,排除项和CSS网格
  18. input框前追加图片
  19. PPP over Ethernet(PPPoE)协议
  20. 国内云服务器,服务商优缺点分析

热门文章

  1. VirtualBox 上的windows XP启动时蓝屏
  2. 安卓源码,跑步打卡项目app源码
  3. php 数据库万能引擎类,ADODB PHP 数据库万能引擎类
  4. JEESNS V1.4 发布,JAVA 开源 SNS 社区系统
  5. 关于SNS社区与行业电子商务结合一些看法
  6. mysql inserted表_数据库inserted的搜索结果-阿里云开发者社区
  7. 美国网红python微博_Python有趣|微博网红大比拼
  8. vue 声明周期函数_Vue 生命周期详解
  9. HDLbits exercises 13(MORE CIRCUITS全部题)
  10. quicklook打开word文字显示不正常