malloc,ralloc,calloc工作原理及其区别

来源:互联网 发布:男士皮鞋品牌 知乎 编辑:程序博客网 时间:2024/05/22 17:09

首先要了解C语言跟内存分配方式

c语言内存有4G空间,其中1G分配给内核,3G分配给用户,其中3G空间又划分为栈空间,堆空间,数据段以及代码段,

下面先说下各个空间各自的存储内容

  (1数据段。里面包括bss(保存为初始化的全局变量),rodata(保存常量),.data(静态数据区,里面全局变量,static修饰变量)。

                  内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。

  (2栈空间。在栈上创建,在执行函数时,函数内的局部变量,形参,自动变量的存储单元都可以在栈上创建,函数执行结束时这些存

                 自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

  (3)堆空间。亦称动态内存分配。里面包括mallocralloccalloc进行动态分配空间,程序员自己负责在何时用freedelete释放内存。

                 动态内存的生存期由我们决定,使用非常灵活,但问题也最多

今天我要说的就是C语言中动态分配空间的函数malloccallocralloc及其工作原理。

 

()malloc.

原型

extern void *malloc(unsigned int num_bytes);

头文件

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

功能

       请求系统动态分配num_bytes个字节的空间,如果分配成功则返回第一个字节的地址,并且可以进行强制类型转换,告诉系统分配

       空间中存储的是那种类型的数据。否则返回空指针NULL

注意:当内存不再使用时,应使用free()函数将内存块释放。

 

():ralloc

原型:extern void *realloc(void *mem_address,unsigned int newsize);

头文件:#include <stdlib.h>

功能

       先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,

       先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域

     (注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

返回值

       如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL

注意

       当内存不再使用时,应使用free()函数将内存块释放。

使用总结

       1. ralloc失败的时候,返回NULL

       2. ralloc失败的时候,原来的内存不改变,不会释放也不会移动

       3. 假如原来的内存后面还有足够多剩余内存的话,ralloc的内存=原来的内存+剩余内存,ralloc还是返回原来内存的地址;

           假如原来的内存后面没有足够多剩余内存的话,ralloc将申请新的内存,然后把原来的内存数据拷贝到新内存里,原

           来的内存将被free,ralloc返回新内存的地址

       4. 如果size0,效果等同于free()

       5. 传递给realloc的指针必须是先前通过malloc(), calloc(),realloc()分配的

       6.传递给realloc的指针可以为空,等同于malloc

 

()calloc

 

函数原型:void *calloc(size_t n, size_t size) 

头文件 #include <stdlib.h> #include<malloc.h>

能:

        在内存的动态分配区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,

        返回NULL

 

在了解了每个函数的基本功能后,说下他们之间的区别

      (1)函数malloc不能初始化所分配的内存空间,也就是说malloc分配好空间后要对所分配的空间进行清理。而函数calloc() 

          会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那么这些

          元素将保证会被初始化为0;如果你是为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针;
      (2)函数malloc向系统申请分配指定size个字节的内存空间.返回类型是 void*类型.void*表示未确定类型的指针. void* 类型

          可以强制转换为任何其它类型的指针.

 

实现原理

         malloc、calloc函数的实质体现在,它有一个将可用的内存连接为一个长长的链表(即所谓的空闲链表)。调用malloc

         函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块,然后将该内存块一分为二(一块的大小与用户申

         请的大小一样,另一块就是剩下的字节),接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话) 

         返回到链表上,调用free函数 时,它将用户释放的内存块连接到空链上,到最后,空闲链表会被切成很多的小内存片段,

         如果这时用户申请一个大的内存片段,那么空闲链上可能没有可能满足用户要求的片段了,于是malloc函数请求延时,并

         开始在空间中翻箱倒柜的检查内存片段,对它们进行整理,并将相邻的小空闲块合成较大的内存块

         realloc是从堆空间上分配内存,当扩大一块内存空间时,realloc试图直接从现存的数据后面的哪些字节中获得附加的字节,

         如果能够满足,自然天下太平,那么如果后面的字节不够,问题就来了,那么就使用堆上第一个足够满足要求的自由空间块,

         现存的数据然后就被拷贝到新的位置上,而老块则放回堆空间,这句话传递的一个很重要的信息就是数据可能被移

原创粉丝点击