malloc和free函数详解

 

  本文介绍malloc和free函数的内容。

  在C中,对内存的管理是相当重要。下面开始介绍这两个函数:

  一、malloc()和free()的基本概念以及基本用法:

1、函数原型及说明:

void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。

关于分配失败的原因,应该有多种,比如说空间不足就是一种。

void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。

2、函数的用法:

其实这两个函数用起来倒不是很难,也就是malloc()之后觉得用够了就甩了它把它给free()了,举个简单例子:

程序代码:
        // Code... 
        char *Ptr = NULL; 
        Ptr = (char *)malloc(100 * sizeof(char)); 
        if (NULL == Ptr) 
     { 
          exit (1); 
    } 
        gets(Ptr); 

        // code... 
        free(Ptr); 
        Ptr = NULL; 
        // code...

就是这样!当然,具体情况要具体分析以及具体解决。比如说,你定义了一个指针,在一个函数里申请了一块内存然后通过函数返回传递给这个指针,那么也许释放这块内存这项工作就应该留给其他函数了。

3、关于函数使用需要注意的一些地方:

A、申请了内存空间后,必须检查是否分配成功。

B、当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。

C、这两个函数应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会

出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。

D、虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。

现在进入第二部分:

  二、malloc()到底从哪里得来了内存空间:

1、malloc()到底从哪里得到了内存空间?答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。关于堆的知识呢可以查询数据结构方面的知识或查询以前的一篇帖子C/C++堆、栈及静态数据区详解[转载]。这里不过多介绍。

2、在使用malloc()分配内存空间后,一定要记得释放内存空间,否则就会出现内存泄漏。

3、free()到底释放了什么

free()释放的是指针指向的内存!注意!释放的是内存,不是指针!指针并没有被释放,指针仍然指向原来的存储空间。指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此,释放内存后把指针指向NULL,防止指针在后面不小心又被解引用了。

  三、malloc()以及free()的机制:

事实上,仔细看一下free()的函数原型,也许也会发现似乎很神奇,free()函数非常简单,只有一个参数,只要把指向申请空间的指针传递给free()中的参数就可以完成释放工作!这里要追踪到malloc()的申请问题了。申请的时候实际上占用的内存要比申请的大。因为超出的空间是用来记录对这块内存的管理信息。

大多数实现所分配的存储空间比所要求的要稍大一些,额外的空间用来记录管理信息——分配块的长度,指向下一个分配块的指针等等。这就意味着如果写过一个已分配区的尾端,则会改写后一块的管理信息。这种类型的错误是灾难性的,但是因为这种错误不会很快就暴露出来,所以也就很难发现。将指向分配块的指针向后移动也可能会改写本块的管理信息。

malloc()申请的空间实际就是分了两个不同性质的空间。一个就是用来记录管理信息的空间,另外一个就是可用空间了。而用来记录管理信息的实际上是一个结构体。在C语言中,经常用结构来记录信息!下面看看这个结构体的原型:

程序代码:
   struct mem_control_block { 
    int is_available;    //一般来说应该是一个可用空间的首地址,但这里英文单词却显示出空间是否可用的一个标记
    int size;            //这是实际空间的大小 
    };

  所以,free()就是根据这个结构体的信息来释放malloc()申请的空间!而结构体的两个成员的大小我想应该是操作系统的事了。
  下面看看free()的源代码

   // code... 
    
       void free(void *ptr)  
    { 
            struct mem_control_block *free; 
            free = ptr - sizeof(struct mem_control_block); 
            free->is_available = 1; 
            return; 
    }

  至于malloc的源码,有兴趣的可以到网上找一下!

malloc 与 free函数详解<转载>的更多相关文章

  1. malloc和free函数详解

    一.malloc()和free()的基本概念以及基本用法: 1.函数原型及说明: void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针 ...

  2. kzalloc 函数详解(转载)

    用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0. view plain /** * kzal ...

  3. Linux中fork()函数详解(转载)

    [原创地址]http://blog.csdn.net/jason314/article/details/5640969 [转载地址]http://www.cnblogs.com/bastard/arc ...

  4. WinMain函数详解(转载)

    略加增添与修改! 工具:VC++6.0       系统:win7 64位 在Windows应用程序中,我们可以认为 WinMain() 函数是程序的入口,WinMain()的原型如下: int WI ...

  5. Interlocked.Increment()函数详解 (转载)

    原文地址 class Program { static object lockObj = new object(); ; ; //假设要处理的数据源 , ).ToList(); static void ...

  6. 【转载】jQuery.extend 函数详解

    转载自:http://www.cnblogs.com/RascallySnake/archive/2010/05/07/1729563.html jQuery.extend 函数详解 JQuery的e ...

  7. 转载_fread函数详解

    fread函数详解 函数原型: size_t   fread(   void   *buffer,   size_t   size,   size_t   count,   FILE   *strea ...

  8. 【转载】3D/2D中的D3DXMatrixPerspectiveFovLH和D3DXMatrixOrthoLH投影函数详解

    原文:3D/2D中的D3DXMatrixPerspectiveFovLH和D3DXMatrixOrthoLH投影函数详解 3D中z值会影响屏幕坐标系到世界坐标系之间的转换,2D中Z值不会产生影响(而只 ...

  9. 【转载】C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    本文转自: C语言itoa()函数和atoi()函数详解(整数转字符C实现) 介绍 C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. int/float to ...

随机推荐

  1. WebGIS项目中利用mysql控制点库进行千万条数据坐标转换时的分表分区优化方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 背景 项目中有1000万条历史案卷,为某地方坐标系数据,我们的真实 ...

  2. [原] Cgroup CPU, Blkio 测试

    关于Cgroup的简单测试 [toc] 简单介绍Cgroup (如果对cgroup熟悉可以忽略) 一般情况下,cgroup挂载到一个虚拟文件目录,然后可以通过文件系统的API对其操作. ># m ...

  3. 介绍一款原创的四则运算算式生成器:CalculateIt2

    家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习.于是,自己在业余时间开发了一个四则运算算式生成器,名为:Calcu ...

  4. [数据结构]——堆(Heap)、堆排序和TopK

    堆(heap),是一种特殊的数据结构.之所以特殊,因为堆的形象化是一个棵完全二叉树,并且满足任意节点始终不大于(或者不小于)左右子节点(有别于二叉搜索树Binary Search Tree).其中,前 ...

  5. MyBatis源码分析(二)语句处理器

    StatementHandler 语句处理器,主要负责语句的创建.参数的设置.语句的执行.不负责结果集的处理. Statement prepare(Connection connection, Int ...

  6. jQuery个性化图片轮播效果

    jQuery个性化图片轮播效果 购物产品展示:图片轮播器<效果如下所示> 思路说明: 每隔一段时间,实现图片的自动切换及选项卡选中效果,鼠标划入图片动画停止,划出或离开动画开始 两个区域: ...

  7. SQL 数据优化索引建suo避免全表扫描

    首先什么是全表扫描和索引扫描?全表扫描所有数据过一遍才能显示数据结果,索引扫描就是索引,只需要扫描一部分数据就可以得到结果.如果数据没建立索引. 无索引的情况下搜索数据的速度和占用内存就会比用索引的检 ...

  8. 免费SSL证书 之Let’s Encrypt申请与部署(Windows Nginx)

    我着着皇帝的新衣,但是你看不见    有一颗愿意等待的心,说明你对未来充满希望.有一颗充满希望的心,那么等待又算什么.人就是在等待与希望中度过,我们永远要对未来充满信心! 读在最前面: 1.本文案例为 ...

  9. JBPM

    JBPM简介 什么是jbpm JBPM,全称是Java Business Process Management(业务流程管理),它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩 ...

  10. 用SSH访问内网主机的方法

    如今的互联网公司通常不会直接自己直接配主机搭建服务器了,而是采用了类似阿里云的这种云主机,当应用变得越来越大了之后,就不可避免地增加主机,而出于成本考虑,不可能给每一台主机都分配公网带宽,所以实际的情 ...