0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

动态内存分配的注意事项及本质是什么

C语言编程学习基地 来源:华为云社区 作者:G-washington 2021-10-13 15:37 次阅读

C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配。

本文分享自华为云社区《 【云驻共创】C语言中动态内存分配的本质 》,作者:G-washington

C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,因为C语言具有可移植性,可拓展性,可重用性等特性,促使C语言仍然在编程语言排行榜上占据一定有利地位。而C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配。

内存分配的概念

通常定义变量(或对象),编译器在编译时都可以根据该变量(或对象)的类型知道所需内存空间的大小,从而系统在适当的时候为他们分配确定的存储空间。这种内存分配称为静态存储分配;

有些操作对象只在程序运行时才能确定,这样编译时就无法为他们预定存储空间,只能在程序运行时,系统根据运行时的要求进行内存分配,这种方法称为动态存储分配。所有动态存储分配都在堆区中进行。

内存不是取之不尽用之不竭,4g、8g、16g是常见的电脑内存大小,打开任务管理器,能看到不同的应用占据的内存情况。如果一个应用程序占了大部分内存,估计别的应用就资源紧张了,那这个应用可能会被卸载,找个节省内存的。

内存管理是计算机接近物理本质的操作,那些程序语言之下的动作,最终都要调动内存来实现。系统的资源不是无限的,系统上运行的程序也不是只有这一个,忽略内存,就会设计出危险的、冗余的代码产品,或者没法更好的交互。

动态内存分配的特点

动态内存是相对静态内存而言的。所谓动态和静态就是指内存的分配方式。动态内存是指在堆上分配的内存,而静态内存是指在栈上分配的内存。动态内存分配的本质就是,什么时候需要一块内存的时候,再分配这块内存;当不再需要某一块内存的时候,就可以把这块内存释放掉。这种灵活的内存分配方式,正好适合链表这种数据结构。

传统数组的缺点

数组与动态内存分配相比有以下缺点:

数组的长度必须事先指定,而且只能是常量,不能是变量。

因为数组长度只能是常量,所以它的长度不能在函数运行的过程当中动态地扩充和缩小。

对于数组所占内存空间程序员无法手动编程释放,只能在函数运行结束后由系统自动释放,所以在一个函数中定义的数组只能在该函数运行期间被其他函数使用。

而“传统数组”的问题,实际上就是静态内存的问题。但是动态内存就不存在这个问题,因为动态内存是由程序员手动编程释的,所以想什么时候释放就什么时候释放。只要程序员不手动编程释放,就算函数运行结束,动态分配的内存空间也不会被释放,其他函数仍可继续使用它。除非是整个程序运行结束,这时系统为该程序分配的所有内存空间都会被释放。

动态内存的申请与释放

动态内存的申请与释放主要依靠两个函数malloc和free。malloc 是一个系统函数,它是 memory allocate 的缩写。其中memory是“内存”的意思,allocate是“分配”的意思。顾名思义 malloc 函数的功能就是“分配内存”,要调用它必须要包含头文件《stdlib.h》。

malloc()函数会向堆中申请一片连续的可用内存空间;若申请成功 ,,返回指向这片内存空间的指针 ,若失败 ,则会返回NULL, 所以我们在用malloc()函数开辟动态内存之后, 一定要判断函数返回值是否为NULL;返回值的类型为void*型, malloc()函数并不知道连续开辟的size个字节是存储什么类型数据的 ,所以需要我们自行决定 ,方法是在malloc()前加强制转 ,转化成我们所需类型 ,如: (int*)malloc(sizeof(int)*n)。

下面使用 malloc 函数写一个程序,程序的功能是:调用被调函数,将主调函数中动态分配的内存中的数据放大 10 倍。

249605c0-2bf7-11ec-82a8-dac502259ad0.png

输出结果是:*p = 100

free是释放函数,在堆中申请的内存空间不会像在栈中存储的局部变量一样 ,函数调用完会自动释放内存 , 如果我们不手动释放, 直到程序运行结束才会释放, 这样就可能会造成内存泄漏, 即堆中这片内存中的数据已经不再使用, 但它一直占着这片空间, 所以当我们申请的动态内存不再使用时 ,一定要及时释放 。不过需要注意的是,释放并不是指清空内存空间,而是指将该内存空间标记为“可用”状态,使操作系统在分配内存时可以将它重新分配给其他变量使用。

那么,当指针变量被释放后,它所指向的内存空间中的数据会怎样呢?free 的标准行为只是表示这块内存可以被再分配,至于它里面的数据是否被清空并没有强制要求。不同的编译器处理的方式可能不一样。我们就看一下 VC++6.0 这个编译器是怎么处理的:

252281da-2bf7-11ec-82a8-dac502259ad0.png

可见在 VC++6.0 中,当指针变量被释放后,虽然它仍然是指向那个内存空间的,但那个内存空间中的值将会被重新置一个非常小的负数。动态创建的内存如果不用了必须要释放。注意,一个动态内存只能释放一次。如果释放多次程序就会崩溃,因为已经释放了,不能再释放第二次。

综上所述,malloc 和 free 一定要成对存在,一一对应。有 malloc 就一定要有 free,有几个 malloc 就要有几个 free,与此同时,每释放一个指向动态内存的指针变量后要立刻把它指向 NULL。

注意事项

1)释放一块内存的一部分是不允许的。动态分配的内存必须整块一起释放。但是,realloc函数可以缩小一块动态分配的内存,有效地释放它尾部的部分内存。

2)不要访问已经被free函数释放了的内存。假定对一个指向动态分配的内存的指针进行了复制,而且这个指针的几份拷贝分散于程序各处。你无法保证当你使用其中一个指针时它所指向的内存是不是已被另一个指针释放。还要确保程序中所有使用这块内存的地方在这块内存释放之前停止对它的使用。

3)当动态分配的内存不再需要使用时,应该被释放,这样可以被重新分配使用。分配内存但在使用完毕后不释放将引起内存泄漏(memory leak)。

今天的分享就到这里了,大家要好好学C++哟~

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7523

    浏览量

    127545
  • 程序
    +关注

    关注

    114

    文章

    3630

    浏览量

    79497
  • 函数
    +关注

    关注

    3

    文章

    3859

    浏览量

    61297
  • 代码
    +关注

    关注

    30

    文章

    4553

    浏览量

    66666
  • 动态内存
    +关注

    关注

    1

    文章

    23

    浏览量

    7917

原文标题:C语言核心基础知识:动态内存分配的本质是什么?

文章出处:【微信号:cyuyanxuexi,微信公众号:C语言编程学习基地】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C语言中的动态内存管理讲解

    本章将讲解 C 中的动态内存管理。C 语言为内存分配和管理提供了几个函数。这些函数可以在 头文件中找到。
    的头像 发表于 02-23 14:03 147次阅读
    C语言中的<b class='flag-5'>动态内存</b>管理讲解

    堆和栈的区别和使用注意事项

    介绍堆和栈的区别和使用注意事项,包括内存分配、数据存储、访问速度、生命周期等方面,帮助读者更好地理解和应用堆和栈。 一、堆和栈的区别 内存分配
    的头像 发表于 01-18 17:24 357次阅读

    芯片金线包封胶的使用注意事项是什么?

    芯片金线包封胶的使用注意事项是什么?金线包封胶是一种高性能、高粘度的密封胶,广泛应用于电子、电器、汽车等领域。它具有良好的防水、防潮、防震等性能,能够保护产品内部零件不受环境影响,提高产品的使用寿命
    的头像 发表于 01-05 11:29 431次阅读
    芯片金线包封胶的使用<b class='flag-5'>注意事项</b>是什么?

    FreeRTOS内存机制详解

    FreeRTOS是一种实时操作系统,它提供了多种内存分配方式,包括动态内存分配和静态内存分配
    的头像 发表于 12-31 16:49 1091次阅读
    FreeRTOS<b class='flag-5'>内存</b>机制详解

    DC电源模块有哪些注意事项和使用技巧?

    DC电源模块有哪些注意事项和使用技巧?
    的头像 发表于 12-25 13:59 231次阅读
    DC电源模块有哪些<b class='flag-5'>注意事项</b>和使用技巧?

    电流互感器的使用注意事项

    当谈到电流互感器的使用时,有一些重要的注意事项需要我们牢记。在本文中,我们将探讨这些注意事项,为您提供详细和全面的信息。
    的头像 发表于 12-15 10:34 554次阅读
    电流互感器的使用<b class='flag-5'>注意事项</b>

    动态补偿装置的元件构成与注意事项有哪些?

    动态补偿装置的元件构成与注意事项有哪些? 动态补偿装置是一种用于对电力系统中的无功功率进行补偿的装置,它通过引入无功功率,来提高电力系统的功率因素,降低无功电流,改善线路的负载情况,从而提高电网运行
    的头像 发表于 11-06 11:27 292次阅读

    DMA开辟缓存怎么使用动态内存

    开辟20kb左右的缓存空间,如果直接用全局变量数组,在不需要用到DMA时,那这20k的内存就一直不能释放,好浪费。若使用malloc来开辟动态内存,应该是放在堆区吧?堆区不是默认只有512字节?还要修改启动文件的堆大小?
    发表于 10-23 06:53

    C语言程序设计中动态内存分配如何实现

    C语言程序设计中,动态内存分配如何实现,需要注意哪些问题?
    发表于 09-28 16:53 843次阅读

    中8位MCU EEPROM使用注意事项

    中颖8位MCU EEPROM使用注意事项
    的头像 发表于 09-27 15:34 485次阅读
    中8位MCU EEPROM使用<b class='flag-5'>注意事项</b>

    使用C语言实现简单动态内存分配

    首先要明白为何需要动态内存分配,熟悉C语言的读者应该对这个比较熟悉,需要一段内存时会使用malloc函数来申请所需要大小的内存,函数返回一段内存
    发表于 07-28 16:26 385次阅读
    使用C语言实现简单<b class='flag-5'>动态内存</b><b class='flag-5'>分配</b>

    安全光栅选择注意事项

    安全光栅选择注意事项
    的头像 发表于 07-14 10:24 543次阅读
    安全光栅选择<b class='flag-5'>注意事项</b>

    使用注意事项

    使用注意事项
    发表于 07-07 19:04 0次下载
    使用<b class='flag-5'>注意事项</b>

    安全光幕选型方法以及注意事项

    安全光幕选型方法以及注意事项
    的头像 发表于 07-06 13:59 459次阅读
    安全光幕选型方法以及<b class='flag-5'>注意事项</b>

    安全光幕选型方法以及注意事项

    安全光幕选型方法以及注意事项
    的头像 发表于 06-28 14:35 452次阅读
    安全光幕选型方法以及<b class='flag-5'>注意事项</b>