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

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

3天内不再提示

周立功:动态分布内存——malloc()函数与calloc()函数

AGk5_ZLG_zhiyua 来源:互联网 作者:佚名 2017-08-22 17:01 次阅读

周立功教授数年之心血之作《程序设计与数据结构》,电子版已无偿性分享到电子工程师与高校群体,在公众号回复【程序设计】即可在线阅读。书本内容公开后,在电子行业掀起一片学习热潮。经周立功教授授权,本公众号特对本书内容进行连载,愿共勉之。

第一章为程序设计基础,本文为1.9.1 malloc()函数和1.9.2 calloc()函数。

》》》》 1.9 动态分配内存

首先回顾一下内存分配,所有程序都必须预留足够的内存存储程序使用的数据,这些内存中有些是自动分配的。比如,声明“int iNum;”为一个int类型的值预留了足够的内存,或显式指定分配一定数量的内存,“int pData[20];”声明预留了20个内存位置,每个位置存储的是int类型的值。声明还为内存提供了标识符,因此可以使用iNum或pData识别数据。静态数据在程序载入内存时分配的,自动数据是在程序执行时分配的,并在程序离开时销毁。但C能做的远不止这些,可以在程序运行时请求所需要的内存大小。

程序在运行时分配的内存空间称之为“堆”的存储池,虽然计算机在硬件上不直接支持堆,但C函数库(stdlib.h)分别提供了用于动态内存分配和释放的函数malloc()和free(),即在运行时根据需要创建一个存储单元,在不需要时释放。

》》》 1.9.1 malloc()函数

malloc()函数原型如下:

void *malloc(unsigned int size);

其中,void *表示该函数是指针函数,size为所需内存的字节数,可以用sizeof运算符计算每个元素所需要的空间数量和所有元素需要内存的字节数。如果分配成功,虽然malloc()不会为分配的内存赋名,但它确实返回了动态分配内存块的首字节地址。因此可以将该地址赋给一个指针变量,并使用指针变量访问这块内存。如果分配不成功或内存不足,则返回空指针NULL。因此在使用它返回的指针之前,一定要先检查返回值,否则可能会导致程序非正常终止。比如:

int *pi = malloc(sizeof(int));

if(pi != NULL){

// 指针没有问题

}else{

// 无效的指针

}

malloc()函数可用于返回指向数组的指针、指向结构的指针等,所以通常该函数的返回值会被强制转换为匹配的类型,但从C99版本开始,void *类型的指针不需要强制转换地赋给所有的指针类型变量。

当编写程序时,常常很难为数组估计合适的大小,较为方便的做法是等到程序运行时,再来确定数组的实际大小。其方法是用malloc()在程序执行期间为数组分配空间,然后通过指向数组第一个元素的指针访问数组。假设正在编写的程序需要n个整数构成的数组,这里的n可以在程序执行期间计算出来。首先需要声明指针变量:

int * pi, n;

一旦n的值已知,就让程序调用malloc()函数为数组分配存储空间:

pi = malloc(n * sizeof(int));

if(pi == NULL) return -1;

当pi指向分配动态分配的内存块时,就可以忽略pi是指针的事实,将它作为数组名使用,这是C语言数组和指针形成紧密关系的所带来的便利。由于数组名是该数组首元素的地址,如果让pi指向这个块的首元素,便可以象使用数组名一样使用它。即可以使用pi[0]访问该块的首元素,pi[1]访问第2个元素,以此类推。比如,使用下列循环对pi指向的数组进行初始化:

for(i = 0; i 《 n; i++) pi[i] = 0;

动态内存分配可以提供更多的灵活性,比如:

char *pcStr;

char *pcStr = malloc(strlen(“OK!”) + 1);

strcpy(pcStr, “OK!”);

在这里,使用strlen()计算字符串的长度,一定要记得加上结束符NUL。为何不用sizeof呢?因为szieof会返回数组和指针的长度,而不是字符串的长度。

》》》 1.9.2 calloc()函数

虽然可以用malloc()函数为数组分配内存,但C语言提供了一种更好用的calloc()函数,其函数原型如下:

void *calloc(size_t nmenb, size_t size);

calloc()函数为nmemb个元素的数组分配内存空间,其中,每个元素的长度都是size个字节。如果要求的空间无效,那么此函数返回指针。在分配了内存之后,calloc()函数会通过将所有位设置为0的方式进行初始化。比如,调用calloc()函数为n个整数的数组分配存储空间,且保证所有整数初始化为0。比如:

pi = calloc(n, sizeof(int));

因为calloc()函数会清楚分配的内存,而malloc()函数不会,所以可以调用以“1”作为第一个实参的calloc()函数,为任何类型的数据项分配空间。比如:

struct point{ int x, y;} *pi;

pi = calloc(1, sizeof(struct point));

在执行此语句后,pi将指向一个结构体,且此结构体的成员x和y都会被设为0。

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

    关注

    38

    文章

    130

    浏览量

    37076
  • 大数据
    +关注

    关注

    64

    文章

    8643

    浏览量

    136585
  • malloc
    +关注

    关注

    0

    文章

    52

    浏览量

    38

原文标题:周立功:动态分布内存——malloc()函数与calloc()函数

文章出处:【微信号:ZLG_zhiyuan,微信公众号:ZLG致远电子】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如果没有用到malloc和free函数,是否会有ram动态使用率这一概念?

    如果没有用到malloc和free函数,是否会有ram动态使用率这一概念?
    发表于 04-12 06:29

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

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

    malloc 申请内存的两种方式

    我们知道malloc() 并不是系统调用,也不是运算符,而是 C 库里的函数,用于动态分配内存malloc 申请
    的头像 发表于 11-13 11:42 1144次阅读
    <b class='flag-5'>malloc</b> 申请<b class='flag-5'>内存</b>的两种方式

    mtrace分析内存泄露

    声明及定义,函数原型为: void mtrace ( void ) ; mtrace原理 mtrace() 函数会为那些和动态内存分配有关的函数(譬如
    的头像 发表于 11-13 10:55 917次阅读
    mtrace分析<b class='flag-5'>内存</b>泄露

    malloc在Linux上执行的是哪个系统调用

    malloc底层为什么是内存malloc大家都用过,其是库函数。我们都知道库函数在不同的操作系统中其实执行的是系统调用,那么
    的头像 发表于 11-13 10:36 489次阅读
    <b class='flag-5'>malloc</b>在Linux上执行的是哪个系统调用

    new和malloc的区别

    1. 申请的内存所在位置 new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上
    的头像 发表于 11-11 11:29 334次阅读
    new和<b class='flag-5'>malloc</b>的区别

    malloc跟free的源码分析

    _int_malloc()函数,_int_malloc()函数才是内存分配的核心实现。 public_m
    的头像 发表于 11-09 11:39 383次阅读

    如何绑架C语言标准库函数

    C语言动态内存可以使用 malloc 标准库函数,而 C++ 会使用 new 关键字申请,裸机情况下一般没有问题,但是在 RTOS 情况下,就需要考虑资源保护的情况,比如多个任务同时
    发表于 11-01 09:50 248次阅读

    如何绑架C语言标准库函数

    C语言动态内存可以使用 malloc 标准库函数,而 C++ 会使用 new 关键字申请,裸机情况下一般没有问题,但是在 RTOS 情况下,就需要考虑资源保护的情况
    发表于 11-01 09:50 125次阅读

    程序内存分布RW Size是否包含malloc申请的大小?

    程序内存分布RW Size是否包含malloc申请的大小
    发表于 10-16 06:46

    C语言malloc申请内存时的碎片问题

    解决问题:malloc在申请内存的时候,内存碎片问题会导致原本内存大小足够,却申请大内存失败。
    发表于 08-06 16:58 1002次阅读
    C语言<b class='flag-5'>malloc</b>申请<b class='flag-5'>内存</b>时的碎片问题

    FreeRTOS内存管理简介

    ,比如任务创建函数 xTaskCreateStatic(),使用此函数创建任务的时候需要由用户定义任务堆栈,我们不讨论这种静态方法。 使用动态内存管理的时候 FreeRTOS 内核在创建任务、队列、信号量的时候会
    的头像 发表于 07-30 10:26 406次阅读

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

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

    什么是堆内存?存储方式是什么样的?

    中的存储方式。 C 代码中动态申请堆内存的申请函数malloc ,常见的内存代码如下图所示: 因为m
    的头像 发表于 06-22 10:29 762次阅读
    什么是堆<b class='flag-5'>内存</b>?存储方式是什么样的?

    浅谈 malloc 函数在单片机上的应用

    聊聊 malloc函数 在单片机程序设计中怎么使用
    的头像 发表于 05-18 09:35 1491次阅读
    浅谈 <b class='flag-5'>malloc</b> <b class='flag-5'>函数</b>在单片机上的应用