首页 > 系统相关 >C和指针:动态内存分配(malloc,calloc,realloc,free)

C和指针:动态内存分配(malloc,calloc,realloc,free)

时间:2024-09-19 10:53:44浏览次数:11  
标签:malloc realloc void free 内存 calloc 指针 size


 动态内存分配

⭐关联知识点:linux动态内存分配

为什么使用动态内存分配

声明数组必须用一个编译时常量指定数组的长度。但是,数组的长度常常在运行时才知道,由于它所需要的内存空间取决于输入数据。

malloc和 free

malloc 和 free,分别用于执行动态内存分配和释放。这些函数维护一个可用内存池。当一个程序另外需要一些内存时,它就调用malloc 函数,malloc 从内存池中提取一块合适的内存,并向该程序返回一个指向这块内存的指针。这块内存此时并没有以任何方式进行初始化。如果对这块内存进行初始化非常重要,你要么自已动手对它进行初始化,要么使用 calloc函数。当一块以前分配的内存不再使用时,程序调用 free 函数把它归还给内存池供以后之需。

void *malloc( size_t size);
void free( void *pointer );

malloc的参数就是需要分配的内存字节数。如果内存池中的可用内存可以满足这个需求,malloc 就返回一个指向被分配的内存块起始位置的指针(void *),一个 void *类型的指针可以转换为其他任何类型的指针。

如果内存池是空的,或者内存不足,malloc函数(brk或者mmap)向操作系统请求,要求得到更多的内存,并在这块新内存上执行分配任务。如果操作系统无法向 malloc 提供更多的内存,malloc 就返回一个NULL指针。对每个从 malloc返回的指针检查,确保非NULL。

malloc所分配的是一块连续的内存(逻辑地址连续),对于要求边界对齐的机器,malloc所返回的内存的起始位置将满足对边界对齐要求的要求。

free的参数要么是NULL,要么是一个malloc、calloc或 realloc返回的值。向 free 传递一个NULL 参数不会产生任何效果。

calloc和 realloc

void *calloc( size_t num_elements,size_t element_size);

void realloc( void *ptr, size_t new_size);

  • calloc也用于分配内存。
  1. malloc和 calloc之间的主要区别是calloc在返回指向内存的指针之前把申请的内存初始化为0。这个初始化常常能带来方便,但如果程序只把一些值存储到数组中,那么这个初始化纯属浪费时间。
  2. calloc 和 malloc 之间另一个小区别是请求内存数量的方式不同。calloc 的参数包括所需元素的数量和每个元素的字节数,然后计算出总共需要分配的内存。

realloc 修改一个原先已经分配的内存块的大小,可以使一块内存扩大或缩小。

(1)如果它用于扩大一个内存块,那么这块内存原先的内容依然保留,新增加的内存添加到原先内存块的后面,新内存并未以任何方法进行初始化。

(2)如果它用于缩小一个内存块,该内存块尾部的部分内存便被拿掉,剩余部分内存的原先内容依然保留。

(3)如果原先的内存块无法改变大小,realloc将分配另一块正确大小的内存,并把原先那块内存的内容复制到新的块上,返回一个新指针。

(4)如果realloc函数的第1个参数是NULL,那么它的行为就和 malloc一模一样。

使用动态分配的内存
int *pi;
pi = malloc( 25* sizeof( int ));//申请25个整数
int &pi2 = pi;
for(i= 0;i< 25;i+= 1)
*pi2++ = 0;//使用指针访问动态数组
//pi[i]=0;//使用下标访问动态数组
常见的动态内存错误

常见动态内存错误包括忘记检查所请求的内存是否成功分配对NULL指针解引用,操作、对分配的内存进行操作时越过边界、释放并非动态分配的内存、试图释放一块动态分配的内存的一部分以及一块动态内存被释放之后被继续使用。

可以封装一个函数来防止对NULL指针进行解引用。

void * alloc( size_t size ){
   void *new_mem;
   /*请求所需的内存,并检查确实分配成功*/
   new_mem=malloc( size);
   if(new_mem==NULL){
    printf( "Out of memory!\n");
    exit(1);
   }
  return new_mem;
}

内存泄漏

分配内存但在使用完毕后不释放将引起内存泄漏(memory leak)。在那些所有执行程序共享一个通用内存池的操作系统中,内存泄漏将一点点地榨干可用内存,最终使其一无所有。要摆脱这个困境,只有重启系统。

标签:malloc,realloc,void,free,内存,calloc,指针,size
From: https://blog.51cto.com/u_16969274/12054969

相关文章

  • 龙芯+FreeRTOS+LVGL实战笔记(新)——08RGB闪烁灯
            本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了完善与优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以前......
  • 【YashanDB知识库】YAS-02025 no free space in virtual memory pool
    本文转自YashanDB官网,具体内容请见[https://www.yashandb.com/newsinfo/7304719.html?templateId=1718516]【标题】YAS-02025nofreespaceinvirtualmemorypool【问题分类】业务SQL执行【关键字】YAS-02025【问题描述】在崖山环境查询数据提示报错YAS-02025nofreespa......
  • C 语言内存管理语法全解析(malloc、calloc、free)
    目录一、引言二、动态内存分配1.malloc函数2.calloc函数 3.realloc函数 三、内存释放 1.free函数 2.内存泄漏的避免四、内存管理的最佳实践1.检查内存分配的返回值2.避免内存访问越界  3.释放内存的顺序4.使用内存管理工具五、总结 一、引言   ......
  • freeRTOS源码解析4--tasks.c 4
    4.2.9周期任务用的延迟--xTaskDelayUntil接口:BaseType_txTaskDelayUntil(TickType_t*constpxPreviousWakeTime,constTickType_txTimeIncrement)形参1:pxPreviousWakeTime,上一次唤醒时间,第一次需要用接口xTaskGetTickCount()获取;形参2:xTimeIncrement,想要延迟的时间。......
  • FreeSwitch之TTS 对接paddlespeech (windowsJava版)
    本来计划FreeSwitch通过tts_commandline对接第三方语音合成,但是由于在家安装的是windows版本,系统安装后mod缺少commandline模版,所以导致无法使用该模版。系统自带的TTS引起filter效果非常差,且不支持中文语音合成,导致在测试的过程中很多工作进行不下去。家里的电脑是windows10......
  • 安装mayavi命令,使用cxfreeze打包python脚本
    pipinstallnumpy出现Anewreleaseofpipisavailable:23.2.1->24.2输入:python-mpipinstall--upgradepipsetuptoolswheelpipinstallPyQt5pipinstallvtkpipinstallmayavipipinstallscipypipinstallconfigobj 查看当前项目的依赖包:pipfr......
  • FreeBSD兼容模式linux账户指向FreeBSD账户造成的困扰
    发现FreeBSD兼容模式linux账户指向FreeBSD账户,这导致账户出现了紊乱。比如FreeBSD下账户guest的id是1001,linux兼容模式下的guest账户id是1004#FreeBSD下目录归属drwxr-xr-x71skywalkskywalk1089月613:59skywalk#Linux下mud归属drwxr-xr-x71linuxskywalk......
  • kubectl top输出与Linux free命令不一致原因
    kubectltop命令和Linux的free命令都用于查看系统资源的使用情况,但它们的输出可能不一致,原因主要包括以下几点:1.数据来源不同kubectltop:该命令从Kubernetes的MetricsServer收集节点和Pod的资源使用情况。MetricsServer会定期收集容器的CPU和内存使用数据,并......
  • freeRTOS源码解析4--task.c 3
    4.2.6任务删除--vTaskDelete这个接口并不复杂,主要是在判断是否要放到xTasksWaitingTermination列表里,还是直接处理。1voidvTaskDelete(TaskHandle_txTaskToDelete)2{3TCB_t*pxTCB;4BaseType_txDeleteTCBInIdleTask=pdFALSE;5BaseTyp......
  • 龙芯+FreeRTOS+LVGL实战笔记(新)——03完成驱动的移植
            本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了改进和优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以前......