malloc()、free()函数详解

        一直以来对malloc()函数和free()函数都只是会用而已,而并未尝试去理解其深刻的内涵,今天就写写自己的一些认识,有很多也是自己刚刚学到的。

 malloc的全称是memory allocation,中文叫动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。

原型

         externvoid *malloc(unsigned int num_bytes);

例如要动态申请一片15个char型的连续空间,可以:

char * str1;  str1=(char*)malloc(sizeof(char)*15);

头文件

         在TC2.0中可以用malloc.h或 alloc.h (注意:alloc.h 与 malloc.h 的内容是完全一致的),而在Visual C++6.0中可以用malloc.h或者stdlib.h

功能

         分配长度为num_bytes字节的内存

返回值

         如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象

说明

         关于该函数的原型,在以前malloc返回的是char指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。

工作机制

         malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。free()释放的是指针指向的内存!注意!释放的是内存,不是指针!这点非常非常重要!指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容是未定义的。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。

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

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

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

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

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

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

        

函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别。 

malloc()函数有一个参数,即要分配的内存空间的大小: 
void *malloc(size_t size); 
calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小。 
void *calloc(size_t numElements,size_t sizeOfElement); 
如果调用成功,函数malloc()和函数calloc()都将返回所分配的内存空间的首地址。 
         函数malloc()和函数calloc()的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存曾经被分配过,则其中可能遗留有各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常进行,但经过一段时间(内存空间还已经被重新分配)可能会出现问题。 
         函数calloc()会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那麽这些元素将保证会被初始化为0;如果你是为指针类型的元素分配内存,那麽这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零。

下面这个例子演示了如何使用malloc()、calloc()、以及free()函数,其中还涉及了一些内部细节:

#include<stdio.h>
#include<stdlib.h>  //malloc()、calloc()、free()函数必要的头文件,也可用<malloc.h>
#include<string.h>
int main()
{
    char *str1;
    char *str2;
    char *str3;
    str1=(char*)malloc(sizeof(char)*15);//动态申请15个char大小的空间
    str2=(char*)malloc(sizeof(char)*15);
    str3=(char*)calloc(2,sizeof(char)*8);//注意这里有两个参数,如果大小改为sizeof(char)*2;
                                   //即只能放4个字符,后面的I like program!就无法存下
    if(str1==NULL)
    {printf("malloc failed!\n");return 0;}
    strcpy(str1,"hello, "); strcpy(str2,"world !");//写内存,不一定写满,但无法写超过
    strcpy(str3,"I like program!");
    printf("%.8x\n",str2);printf("%.8x\n",str3);//查看分配内存的首地址,可能不同的编译器处理方式不同
    printf("%s%s\n",str1,str2);
    printf("%s\n",str3);
    free(str1);free(str2);free(str3);     //注意一定要释放空间,虽然不释放对程序运行结果
    return 0;                             //看似没有影响,但对操作系统内部就不一定了。
}

程序运行结果:


 如果将程序第13行改为 :

str3=(char*)calloc(2,sizeof(char)*2);//注意这里有两个参数,如果大小改为sizeof(char)*2,

                                     //即只能放4个字符,后面的I like program!就无法存下

程序运行后会报错:提示访问了非法内存,即程序尝试修改未申请的内存单元。


 

 

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值