原文地址:http://www.cnblogs.com/3me-linux/p/3962152.html

calloc(), malloc(), realloc(), free(),alloca()

内存区域可以分为栈、堆、静态存储区和常量存储区,局部变量,函数形参,临时变量都是在栈上获得内存的,它们获取的方式都是由编译器自动执行的。
利用指针,我们可以像汇编语言一样处理内存地址,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字节.
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);

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可以指定个数和大小,而且能够对分配内存进行初始化,其余函数均不会对内存进行初始化工作,需要自行调用memset()函数.

C:malloc/calloc/realloc/alloca内存分配函数的更多相关文章

  1. malloc/calloc/realloc/alloca内存分配函数

    calloc(), malloc(), realloc(), free(),alloca() 内存区域可以分为栈.堆.静态存储区和常量存储区,局部变量,函数形参,临时变量都是在栈上获得内存的,它们获取 ...

  2. C语言 malloc calloc realloc alloc 在分配内存时的 区别

    malloc : 向堆申请分配内存,不初始化 calloc  : 向堆申请分配内存,初始化为0 realloc:  向堆申请分配内存,可调整大小 alloc   :   向栈申请内存,不需手动释放

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

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

  4. 内存分配函数malloc、realloc、calloc、_alloca

    1.内存分配函数_alloca.malloc.realloc.calloc: _alloca 函数原型void * __cdecl _alloca(size_t); 头文件:malloc.h _all ...

  5. C语言内存分配函数malloc——————【Badboy】

    C语言中经常使用的内存分配函数有malloc.calloc和realloc等三个,当中.最经常使用的肯定是malloc,这里简单说一下这三者的差别和联系. 1.声明 这三个函数都在stdlib.h库文 ...

  6. C标准库-数值字符串转换与内存分配函数

    原文链接:http://www.orlion.ga/977/ 一.数值字符串转换函数 #include <stdlib.h> int atoi(const char *nptr); dou ...

  7. malloc calloc realloc,new区别联系以及什么时候用

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

  8. C语言之内存分配函数

    #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { /********* ...

  9. malloc,calloc,realloc三者的区别

    malloc,calloc,realloc三者都可以运用与动态分配数组. malloc:用malloc必须要自己初始化,可以用memset(arr,0,cnt*sizeof(int)) calloc: ...

随机推荐

  1. git 28原则

    一.流程 $ git init # 创建一个新的仓库 sublime 编写文本,不要使用win自带文本编辑器 $ git add file1 # 将文件添加到暂存区 $ git add file2 $ ...

  2. Java -- JDBC 学习--通过Statement进行数据库更新操作

    通过 JDBC 向指定的数据表中插入一条记录. 1. Statement: 用于执行 SQL 语句的对象 1). 通过 Connection 的 createStatement() 方法来获取 2). ...

  3. centos6.5之Hadoop1.2.1完全分布式部署安装

    0. 说明 系统中首先要安装好jdk环境. 已经配置ssh免密码登录. 设置好防火墙,或者关闭防火墙. 如果集群内机器的环境完全一样,可以在一台机器上配置好,然后把master配置好的软件即hadoo ...

  4. 【POJ1734】Sightseeing Trip 无向图最小环

    题目大意:给定一个 N 个顶点的无向图,边有边权,如果存在,求出该无向图的最小环,即:边权和最小的环,并输出路径. 题解:由于无向图,且节点数较少,考虑 Floyd 算法,在最外层刚开始遍历到第 K ...

  5. HTTP/1.1 100 Continue - I 服了 You

    今天用 c 的 socket() 模拟发送http请求:上传一张图片到服务器. 在本地测试,本地电脑: xp, iis5.1 经过半天时间对 http post file 协议的了解,代码已经写好,测 ...

  6. wagger的展示路径修改

    转:https://www.jianshu.com/p/ce7e247515f5?utm_source=oschina-app 注:本文是基于springboot配置实现,但在实际中使用springm ...

  7. 何谓SQL Server参数嗅探

    大家听到"嗅探"这个词应该会觉得跟黑客肯定有关系吧,使用工具嗅探一下参数,然后截获,脱裤o(∩_∩)o . 事实上,我觉得大家太敏感了,其实这篇文章跟数据库安全没有什么关系,实际上 ...

  8. GO语言的进阶之路-爬虫进阶之路

    GO语言的进阶之路-爬虫进阶之路 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 网络爬虫是一种自动获取网页内容的程序,是搜索引擎的重要组成部分.我们今天要介绍的就是一个简单的网络爬 ...

  9. IP基本原理

    IP基本原理 一.IP基本原理 IP是网络层协议,也是当今应用最广泛的网络协议之一 IP协议规定了数据的封装方式,网络节点的标识方法,用于网络上数据的端到端的传递. 1.IP及其相关协议 2.IP的主 ...

  10. OS + CentOS 7 / centos 7 / VirtualBox /vegrant

    s VirtualBox:解决VirtualBox安装时libSDL-1.2.so.0()错误的问题. http://www.sklinux.com/983 为Centos6.2安装VirtualBo ...