关于malloc,realloc和free函数的讲解

最近由于准备考研了,在看到数据结构这块的时候。想动手把书上的代码都实现了。但是由于好长时间没有后写过C的代码,对这几个函数有点疑惑,于是整理了资料。
1. malloc详解
【以下俩点是以前没有注意到的地方】
1) 因为mallo函数返回值是void类型,所以我们必须强制转换指针类型  
int* p = (int *)malloc (sizeof(int));
2)malloc分配的内存空间在逻辑上连续的,而在物理上可以连续也可以不连续

 1.原型:extern void *malloc(unsigned int num_bytes);
   头文件:#include<malloc.h> 或 #include <alloc.h> (注意:alloc.h 与 malloc.h 的内容是完全一致的。)

   功能:分配长度为num_bytes字节的内存块

   说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

   当内存不再使用时,应使用free()函数将内存块释放。
     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得到指针,在其它操作上保持一致。
    总结:
   malloc()函数其实就在内存中找一片指定大小的空间,然后将这个空间的首地址范围给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc()函数中参数size的具体内容。我们这里malloc分配的内存空间在逻辑上连续的,而在物理上可以连续也可以不连续。对于我们程序员来说,我们关注的是逻辑上的连续,因为操作系统会帮我们安排内存分配,所以我们使用起来就可以当做是连续的。

2. realloc详解

       #include<stdlib.h>
       1.realloc(void *__ptr, size_t __size):更改已经配置的内存空间,即更改由malloc()函数分配的内存空间的大小。
       2.如果将分配的内存减少,realloc仅仅是改变索引的信息。
       3.如果是将分配的内存扩大,则有以下情况:
       1)如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。
       2)如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。
       3)如果申请失败,将返回NULL,此时,原来的指针仍然有效。
3.    include<stdio.h>
          include<stdlib.h>
          int main(){
              int *test=(int *)calloc(1,sizeof(int));
              if(!test)
                  printf("分配内存错误\n");
              else{
                  printf("指针地址:%X\n",(unsigned int)test);
                  printf("指向内存的内容:%d\n",*test);
                  printf("释放它\n");
                  free(test);
                  printf("释放后,指针的地址:%X\n",(unsigned int)test);
                  printf("释放后,指针指向的内存的内容:%d\n",*test);
              }
              return 0;
          }
     通过上面的小程序,可以看出,在free前后,指针test并没有改变,那么free到底怎么工作呢?
查看man 3 free,其中也没有说明白,只是说free释放掉指定参数指针指向的内存,并返回void。其实,free函数只是将参数指针指向的内存归还给操作系统,并不会把参数指针置NULL,为了以后访问到被操作系统重新分配后的错误数据,所以在调用free之后,通常需要手动将指针置NULL。从另一个角度来看,内存这种底层资源都是由操作系统来管理的,而不是编译器,编译器只是向操作系统提出申请。所以free函数是没有能力去真正的free内存的。只是告诉操作系统它归还了内存,然后操作系统就可以修改内存分配表,以供下次分配。

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值