内存区域可以分为栈、堆、静态存储区和常量存储区,局部变量,函数形参,临时变量都是在栈上获得内存的,它们获取的方式都是由编译器自动执行的。

利用指针,我们可以像汇编语言一样处理内存地址,C 标准函数库提供了许多函数来实现对堆上内存管理,其中包括:malloc函数,free函数,calloc函数和realloc函数。使用这些函数需要包含头文件stdlib.h。

  四个函数之间的有区别,也有联系,我们应该学会把握这种关系,从而编出精炼而高效的程序。

在说明它们具体含义之前,先简单从字面上加以认识,前3个函数有个共同的特点,就是都带有字符”alloc”,就是”allocate”,”分配”的意思,也就是给对象分配足够的内存,” calloc()”是”分配内存给多个对象”,” malloc()”是”分配内存给一个对象”,”realloc()”是”重新分配内存”之意。”free()”就比较简单了,”释放”的意思,就是把之前所分配的内存空间给释放出来。

void *calloc(size_t nobj, size_t size);

  分配足够的内存给nobj个大小为size的对象组成的数组, 并返回指向所分配区域的第一个字节的指针;

  若内存不够,则返回NULL. 对于分配到的内存块初始化为0,无需要使用memset初始化。有经验的程序员更喜欢使用calloc(),因为这样的话新分配内存的内容就不会有什么问题,调用calloc()肯定会清0。

  char *p = (char *) calloc(100,sizeof(char));

void *malloc(size_t size);

  分配足够的内存给大小为size的对象, 并返回指向所分配区域的第一个字节的指针;

  若内存不够,则返回NULL. 不对分配的空间进行初始化.

  char *p = (char *)malloc(sizeof(char));

void *realloc(void *p, size_t size);

  将p所指向的对象的大小改为size个字节.

  如果新分配的内存比原内存大, 那么原内存的内容保持不变, 增加的空间不进行初始化.

  如果新分配的内存比原内存小, 那么新内存保持原内存的内容, 增加的空间不进行初始化.

  返回指向新分配空间的指针; 若内存不够,则返回NULL, 原p指向的内存区不变.

  char *p = (char *)malloc(sizeof(char));

  p= (char *)realloc(p, 256);

对realloc的详细语法说明:

  void *realloc( void *memblock, size_t size ); 
  1、如果memblock = 0, size != 0,表示为空指针分配空间,同malloc(memblock,
size) 
  2、如果memblock != 0, size = 0,表示将已分配的空间释放,同free(memblock) 
  3、如果memblock != 0, size != 0,表示将已分配的空间重新分配, 
    1)、如果size < memblock已分配内存大小,则将memblock的后部分切除,返回指针和memblock相等。 
    2)、如果size > memblock已分配内存大小, 
    (1)、并且memblock大小和其后的自由内存总和大于等于size,则分配size大小的内存,返回指针和memblock相等。 
    (2)、如果memblock大小和其后的自由内存总和小于size,则在其他地方分配size大小的内存,返回指针和memblock不相等。如果其他地方也没有足够空间分配内存,则返回指针NULL。

void free(void *p);

  释放p所指向的内存空间; 当p为NULL时, 不起作用.P必先调用calloc, malloc或realloc.

值得注意的有以下5点:

(1)通过malloc函数得到的堆内存必须使用memset函数来初始化

  malloc函数分配得到的内存空间是未初始化的。因此,一般在使用该内存空间时,要调用另一个函数memset来将其初始化为全0,memset函数的声明如下:void * memset (void * p,int c,int n) ;

  该函数可以将指定的内存空间按字节单位置为指定的字符c,其中,p为要清零的内存空间的首地址,c为要设定的值,n为被操作的内存空间的字节长度。如果要用memset清0,变量c实参要为0。

  malloc函数和memset函数的操作语句一般如下:

  int * p=NULL;

  p=(int*)malloc(sizeof(int));

  if(p==NULL)

  printf(“Can’t get memory!\n”);

  memset(p,0,siezeof(int));

(2)使用malloc函数分配的堆空间在程序结束之前必须释放

  从堆上获得的内存空间在程序结束以后,系统不会将其自动释放,需要程序员来自己管理。一个程序结束时,必须保证所有从堆上获得的内存空间已被安全释放,否则,会导致内存泄露。

  我们可以使用free()函数来释放内存空间,但是,free函数只是释放指针指向的内容,而该指针仍然指向原来指向的地方,此时,指针为野指针,如果此时操作该指针会导致不可预期的错误。安全做法是:在使用free函数释放指针指向的空间之后,将指针的值置为NULL。

(3)calloc函数的分配的内存也需要自行释放

  calloc函数的功能与malloc函数的功能相似,都是从堆分配内存,它与malloc函数的一个显著不同时是,calloc函数得到的内存空间是经过初始化的,其内容全为0。calloc函数适合为数组申请空间,可以将size设置为数组元素的空间长度,将n设置为数组的容量。

(4)如果要使用realloc函数分配的内存,必须使用memset函数对其内存初始化

  realloc函数的功能比malloc函数和calloc函数的功能更为丰富,可以实现内存分配和内存释放的功能。realloc 可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。realloc
并不保证调整后的内存空间和原来的内存空间保持同一内存地址。相反,realloc 返回的指针很可能指向一个新的地址。

  所以,在代码中,我们必须将realloc返回的值,重新赋值给 p :

  p = (int *) realloc(p, sizeof(int) *15);

  甚至,你可以传一个空指针(0)给 realloc ,则此时realloc 作用完全相当于malloc。

  int* p = (int *)realloc (0,sizeof(int) * 10);   //分配一个全新的内存空间,

  这一行,作用完全等同于:

  int* p = (int *)malloc(sizeof(int) * 10);

(5)关于alloca()函数

  还有一个函数也值得一提,这就是alloca()。其调用序列与malloc相同,但是它是在当前函数的栈帧上分配存储空间,而不是在堆中。其优点是:当 函数返回时,自动释放它所使用的栈帧,所以不必再为释放空间而费心。其缺点是:某些系统在函数已被调用后不能增加栈帧长度,于是也就不能支持alloca
函数。尽管如此,很多软件包还是使用alloca函数,也有很多系统支持它。

calloc(), malloc(), realloc(), free(),alloca()的更多相关文章

  1. malloc、calloc、realloc和alloca各种的区别

    需要先包含头文件 #include"malloc.h" malloc是标准的在堆中开辟新的空间 比如 char *pt=(char *)malloc(10*sizeof(char) ...

  2. malloc,calloc,realloc函数用法,原理及不同解析

    https://blog.csdn.net/lixungogogo/article/details/50887028 一.malloc malloc在MSDN中原型为: void *malloc( s ...

  3. 【C/C++开发】malloc,calloc和realloc的区别和注意事项

    (1)C语言跟内存分配方式 <1>从静态存储区域分配.        内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量.static变量. <2&g ...

  4. malloc,calloc,realloc,alloc

    三个函数的申明分别是: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(si ...

  5. malloc,calloc,realloc

    与堆操作相关的两个函数 malloc #include<stdio.h> #include<stdlib.h> #include<string.h> int mai ...

  6. malloc、calloc、realloc的区别

    (1)C语言跟内存分配方式 <1>从静态存储区域分配.       内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量.static变量.<2> ...

  7. 【转】【C/C++】内存分配函数:malloc,calloc,realloc,_alloca

    转自:http://www.cnblogs.com/particle/archive/2012/09/01/2667034.html#commentform malloc: 原型:extern voi ...

  8. c语言中malloc realloc 和calloc的联系与区别

    (1)C语言跟内存分配方式 <1>从静态存储区域分配.       内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量.static变量.<2> ...

  9. malloc realloc calloc free

    自上次发现自己对这几个C函数不熟悉,就打算抽空整理一下,也就现在吧.这几个函数都是跟堆内存打交道的,还有一个好玩的函数--alloca,它是跟栈内存打交道的,我想留在以后研究出好玩点的来,再专门为其写 ...

随机推荐

  1. linux mysql远程连接的命令

    mysql -u 用户名 -h 远程IP地址 -p  随后输入密码. 要确认远程数据库3306端口是否开放,mysql服务是否启动. hadoop@Master:~$ mysql -u root -h ...

  2. winform利用itextsharp.dll实现图片文件转换PDF格式文件

    1.利用itextsharp.dll实现单个图片文件转换为PDF格式文件, 可以使用以下类: void ConvertJPG2PDF(string jpgfile, string pdf) { var ...

  3. fopen flock fclose 文件用法

    fopen函数是用来打开文件或者连接 若成功,则返回 true.若失败,则返回 false. fopen打开连接是不能直接输出的 使用: <?php $file = fopen("te ...

  4. Javascript数组与类数组对象

    问题来由: 之前面试X公司的时候,问我关于原型链知道多少,于是我就开始说了一些有关于原型链的东西,面试官问Array的原型是什么,我说是对象,毕竟Array.prototype===array.__p ...

  5. 新浪股票接口AndroidSDK

    昨天想到一个点子,需要访问股票行情.于是在网上搜了一下免费的股市行情的接口.发现新浪股票的数据接口比较稳定,于是就用它了. 网上对于新浪股票的数据接口介绍比较详细,并且实现也很简单,所以花了一下午就基 ...

  6. 将文件导入到SQL server数据库表中的字段中

    一.在要执行的sql server数据库a中执行如下脚本,创建存储过程sp_textcopy /* 将二进制文件导入.导出到数据库相应字段列中 */ CREATE PROCEDURE sp_textc ...

  7. sql2008,sa不能使用:不能为主体 sa 中设置凭据

    打开属性对话框,为 SQL Server Administrator 帐户,然后您执行了"sa"登录使用 SQL Server Management Studio 工具.您修改为在 ...

  8. generating-ssh-keys

    https://help.github.com/articles/generating-ssh-keys/ 其中 # start the ssh-agent in the background ssh ...

  9. Docker技术原理

    Docker技术原理之Linux Namespace(容器隔离) https://blog.csdn.net/songcf_faith/article/details/82748987 Docker技 ...

  10. docker machine介绍和使用

    https://www.cnblogs.com/sparkdev/p/7044950.html https://www.jianshu.com/p/cc3bb8797d3b