?
当前位置:??编程语言>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?
#include?


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??
#include??
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??
#include??
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???/*?printf,?scanf,?NULL?*/
#include???/*?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


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-2019,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号