c++malloc函数
malloc函数
百科名⽚
本词条主要介绍
malloc 函数
Malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表⽰未确定类型的。C,C++规定,void* 类型可以为任何其它类型的指针。
⽬录
函数简介
函数声明
函数的⼯作机制
举例说明
函数简介
  原型:extern void *malloc(unsigned int num_bytes);
  头⽂件:在TC2.0中可以⽤malloc.h或 alloc.h (注意:alloc.h 与 malloc.h 的内容是完全⼀致的),⽽在Visual C++6.0中可以⽤malloc.h或者。
  功能:分配长度为num_bytes字节的内存块
  返回值:如果分配成功则返回指向被分配内存的(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使⽤时,应使⽤()函数将内存块释放。函数返回的指针⼀定要适当对齐,使其可以⽤于任何。
  说明:关于该函数的原型,在旧的版本中malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进⾏类型转换。
  名称解释:malloc的全称是memory allocation,中⽂叫分配,当⽆法知道内存具体位置的时候,想要绑定真正的内存空间,就需要⽤到动态的分配内存。
  相关函数:、、free、_alloca
函数声明
  void *malloc(size_t size);
  备注:void* 表⽰未确定类型的,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道⽤户是⽤这段空间来存储什么类型的数据(⽐如是char还是int或者...)
  从函数声明上可以看出。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)*128);//分配128个(可根据实际需要替换该数值)整型存储单元,并将这128个连续的整型存储单元的⾸地址存储到p中
  double *pd=(double *) malloc (sizeof(double)*12);//分配12个double型存储单元,并将⾸地址存储到指针变量pd中
  第⼀、malloc 函数返回的是 void * 类型。对于C++,如果你写成:p = malloc (sizeof(int)); 则程序⽆法通过编译,报错:“不能将 void*赋值给 int * 类型”。所以必须通过 (int *) 来将。⽽对于C,没有这个要求,但为了使C程序更⽅便的移植到C++中来,建议养成强制转换的习惯。
  第⼆、函数的为 sizeof(int) ,⽤于指明⼀个需要的⼤⼩。如果你写成:
  int* p = (int *) malloc (1);
  代码也能通过编译,但事实上只分配了1个字节⼤⼩的内存空间,当你往⾥头存⼊⼀个整数,就会有3个字节⽆家可归,⽽直接“住进邻居家”!造成的结果是后⾯的内存中原有数据内容被改写。
  在Linux中可以有这样:malloc(0),这是因为Linux中malloc有⼀个下限值16Bytes,注意malloc(-1)是禁⽌的;
  但是在某些系统中是不允许malloc(0)的。在规范的程序中我们有必要按照这样的格式去使⽤malloc及:
  type *p;
  if (NULL == (p = (type *)malloc(sizeof (type)))) /*请使⽤if来判断,这是有必要的*/
  {
  perror("");
  exit(1);
  }
  ... /*其它代码*/
  free(p);
  p = NULL; /*请加上这句*/
  malloc 也可以达到 new [] 的效果,申请出⼀段连续的内存,⽅法⽆⾮是指定你所需要内存⼤⼩。
  ⽐如想分配100个int类型的空间:
  int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100个整数的内存空间。
  另外有⼀点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进⾏初始化,所以得到的⼀⽚新内存中,其值将是随机的。
  除了分配及最后释放的⽅法不⼀样以外,通过malloc或new得到指针,在其它操作上保持⼀致。
  对其做⼀个特例补充
  char *ptr;
  if ((ptr = (char *)malloc(0)) == NULL)
  puts("Got a null pointer");
  else
  puts("Got a valid pointer");
  此时得到的是Got a valid pointer。把0赋给malloc能得到⼀个合法的指针。
函数的⼯作机制
  malloc函数的实质体现在,它有⼀个将可⽤的内存块连接为⼀个长长的列表的所谓空闲。调⽤malloc函数时,它沿寻⼀个⼤到⾜以满⾜⽤户请求所需要的内存块。然后,将该内存块⼀分为⼆(⼀块的⼤⼩与⽤户请求的⼤⼩相等,另⼀块的⼤⼩就是剩下的字节)。接下来,将分配给⽤户的那块内存传给⽤户,并将剩下的那块(如果有的话)返回到连接表上。调⽤函数时,它将⽤户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的⼩内存⽚段,如果这时⽤户申请⼀个⼤的内存⽚段,那么空闲链上可能没有可以满⾜⽤户要求的⽚段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存⽚段,对它们进⾏整理,将相邻的⼩空闲块合并成较⼤的内存块。如果⽆法获得符合要求的内存块,malloc函数会返回NULL,因此在调⽤malloc动态申请内存块时,⼀定要进⾏返回值的判断。
  Linux Libc6采⽤的机制是在free的时候试图整合相邻的碎⽚,使其合并称为⼀个较⼤的free空间。
举例说明
  正常⽚段:
  typedef struct data_type{
  int age;
  char name[20];
  } data;
  data *bob;
  bob = (data *) malloc( sizeof(data) );
  if( bob != NULL ) {
  bob->age = 22;
  strcpy( bob->name, "Robert" );
  printf( "%s is %d years old\n", bob->name, bob->age );
  }else{
  printf("malloc error!\n");
  exit(1);
  }
  ( bob );
  内存泄漏实例:
  #include <stdio.h>
  #include <malloc.h>
  #define MAX 100000000
  int main(void) {
  int *a[MAX];
  int i;
  for( i=0; i<MAX; i++ ) {
  a[i] = (int *)malloc( MAX );
  }
  return 0;
  }
printf函数原型在什么头文件里