当前位置:  编程语言>c/c++

malloc函数详解及用法举例

 
分享到:
    发布时间:2016-10-6  


    本文导语: malloc动态内存分配函数原理详解及编程用法举例(本文由www.169it.com搜集整理)malloc函数函数原型定义void*malloc(size_tsize);malloc函数原型说明 malloc函数向系统申请分配size个字节的内存空间。返回值类型...

 malloc动态内存分配函数原理详解及编程用法举例(本文由www.169it.com搜集整理)

malloc函数函数原型定义

void *malloc(size_t size);


malloc函数原型说明

     malloc函数向系统申请分配size个字节的内存空间。返回值类型是 void* 类型。void* 表示未确定类型的指针。c,c++规定,void* 类型可以强制转换为任何其它类型的指针。

malloc动态内存分配函数头文件

#include <stdlib.h>
#include <malloc.h>


malloc函数使用要求

这个函数要实现的功能是在系统中分配一段连续的可用的内存,具体有如下要求:

1.malloc分配的内存大小至少为size参数所指定的字节数.

2.malloc的返回值是一个指针,指向一段可用内存的起始地址.

3.多次调用malloc所分配的地址不能有重叠部分,除非某次malloc所分配的地址被释放掉.

4.malloc应该尽快完成内存分配并返回.

5.实现malloc时应同时实现内存大小调整和内存释放函数(即reallocfree).


对于malloc更多的说明可以在linux shell命令行中键入以下命令查看:

  man malloc

可以看见linux下malloc函数的详细使用手册

linux下malloc函数的详细使用手册


与malloc函数相关的函数

calloc()函数、realloc()函数、free()函数


malloc函数用法举例


malloc函数用法实例1

#include<stdio.h>  
#include<malloc.h>  
int main()  
{  
    char *p;  
   
    p=(char *)malloc(100);  
    if(p)  
        printf("Memory Allocated at: %x/n",p);  
    else  
        printf("Not Enough Memory!/n");  
    free(p);  
    return 0;  
}

malloc函数用法实例2


#include<stdio.h>  
#include<malloc.h>  
int main()  
{  
     // Code... 
        char *Ptr = NULL; 
        Ptr = (char *)malloc(100 * sizeof(char)); 
        if (NULL == Ptr) 
     { 
          exit (1); 
    } 
        gets(Ptr); 
        // code... 
        free(Ptr); 
        Ptr = NULL; 
        // code...
}

malloc函数编程实例3

/*
//本文来自 www.169it.com
in参数:申请的堆内存字节数,注意int,short,float需要自己乘上相应字节数。
out返回值:void *
*/
main()
{
char *str=NULL;
str=(char *)malloc(10); //注意malloc返回值是void *,申请时需要强制转换成需要的类型
memset(str,0,10);  //如果不清空,申请的区域值是随机的,养成好习惯
strcpy(str,"happylife"); //使用strcpy特别注意拷贝的字符串长度<=10-1,即要预留字符串结束标志''
puts(str);
free(str);
printf("str[address]:%s[%x]n",str,str);  //这里的str内容为空,但是指针地址还在
str=NULL;  //注意指针free之后该指针仍然存在,最好将它指向为空。
printf("str[address]:%s[%x]n",str,str);  //这里的str内容为空,地址也为空
}

malloc函数动态内存分配编程实例4

#include <stdio.h>  /* printf, scanf, NULL */
#include <stdlib.h>  /* malloc, free, rand, system */
int main ()
{
    int i,n;
    char * buffer;
    printf ("输入字符串的长度:");
    scanf ("%d", &i);
    buffer = (char*)malloc(i+1);  // 字符串最后包含 
    if(buffer==NULL) exit(1);  // 判断是否分配成功
    // 随机生成字符串
    for(n=0; n<i; n++)
        buffer[n] = rand()%26+'a';
    buffer[i]='';
    printf ("随机生成的字符串为:%sn",buffer);
    free(buffer);  // 释放内存空间
    system("pause");
    return 0;
}


malloc函数使用时需要注意的要点:

  1、如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address.  这里说的是“扩大”,我们知道,realloc是从上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize,得到的是一块连续的内存。

  2、如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。  并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。  

  例如: 

 #include
  char *p,*q;
  p = (char * ) malloc (10);
  q=p;
  p = (char * ) realloc (p,20);
  …………………………


  这段程序也许在编译器中没有办法通过,因为编译器可能会为我们消除一些隐患!在这里我们只是增加了一个记录原来内存地址的指针q,然后记录了原来的内存地址p,如果不幸的话,数据发生了移动,那么所记录的原来的


内存地址q所指向的内存空间实际上已经放回到堆上了!这样一来,我们应该终于意识到问题的所在和可怕了吧!

  3、malloc函数返回值情况

  返回的是一个void类型的指针,调用成功。(这就再你需要的时候进行强制类型转换

  返回NULL,当需要扩展的大小(第二个参数)为0并且第一个参数不为NULL,此时原内存变成了“freed(游离)”的了。

  返回NULL,当没有足够的空间可供扩展的时候,此时,原内存空间的大小维持不变。

  4、malloc函数的特殊情况

  如果mem_address为null,则realloc()和malloc()类似。分配一个newsize的内存块,返回一个指向该内存块的指针。

  如果newsize大小为0,那么释放mem_address指向的内存,并返回null。

  如果没有足够可用的内存用来完成重新分配(扩大原来的内存块或者分配新的内存块),则返回null.而原来的内存块保持不变。


malloc()函数和free()函数的机制说明

malloc函数原理

malloc()到底从哪里分配到内存空间?答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。关于堆的知识呢可以查询数据结构方面的知识。在使用malloc()分配内存空间后,一定要记得释放内存空间,否则就会出现内存泄漏

free函数原理

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

函数声明上可以看出malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:

   

  int *p;
   p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);


  或: 

 int* parr;
  parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100; 

    而 malloc 则必须由我们计算要字节数,并且在返回后强行转换为实际类型的指针。   

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

  第一、malloc 函数返回的是 void * 类型,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译报错:“不能将 void* 赋值给 int * 类型变量”。所以必须通过 (int *) 来将强制转换。

  第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。

     如果你写成:  

int* p = (int *) malloc (1);

  代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容全部被清空。

  malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。

  比如想分配100个int类型的空间:  

int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100个整数的内存空间。

  另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。

  除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。


  • 本站(WWW.169IT.COM)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.169IT.COM)站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.
    转载请注明:文章转载自:[169IT-IT技术资讯]
    本文标题:malloc函数详解及用法举例
相关文章推荐:


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2017,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号