C/C++中的malloc、calloc和realloc
1. malloc
原型:extern void *malloc(unsigned int num_bytes);
头文件:Visual C++6.0中可以用malloc.h或者stdlib.h
功能:分配长度为num_bytes字节的内存块
返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
函数声明:void *malloc(size_t size);
说明:malloc向系统申请分配指定size个字节的内存空间。返回类型是void*类型。void*表示未确定类型的指针。C,C++规定,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;
//分配128个(可根据实际需要替换该数值)整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中
p = (int *) malloc (sizeof(int)*128);
//分配12个double型存储单元,并将首地址存储到指针变量pd中
double *pd=(double *) malloc (sizeof(double)*12);
使用malloc时要注意:
malloc函数返回的是void *类型。对于C++,如果你写成:p = malloc (sizeof(int));则程序无法通过编译,报错:“不能将void*赋值给int *类型变量”。所以必须通过(int *)来将强制转换。而对于C,没有这个要求,但为了使C程序更方便的移植到C++中来,建议养成强制转换的习惯- 函数的实参为
sizeof(int),用于指明一个整型数据需要的大小。如果你写成:
int* p = (int *) malloc (1);
代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容被改写。
malloc内部机制
malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free()函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。
2. calloc
函数声明:void *calloc(unsigned n,unsigned size);
功能:在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针,如果分配不成功,返回NULL。
与malloc的区别:
calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
3. realloc
原型:extern void *realloc(void *mem_address, unsigned int newsize);
头文件:#include <stdlib.h>
功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
返回值:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
使用语法:指针名 = (数据类型*)realloc(要改变内存大小的指针名,新的大小)。//新的大小一定要大于原来的大小不然的话会导致数据丢失!
注意:这里原始内存中的数据还是保持不变的。当内存不再使用时,应使用
free()函数将内存块释放。
C/C++中的malloc、calloc和realloc的更多相关文章
- malloc calloc 和 realloc
realloc()函数 原型:extern void *realloc(void *mem_address, unsigned int newsize); 语法:指针名=(数据类型*)realloc( ...
- 【C/C++开发】malloc,calloc和realloc的区别和注意事项
(1)C语言跟内存分配方式 <1>从静态存储区域分配. 内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量.static变量. <2&g ...
- C 语言中 malloc、calloc、realloc 和free 函数的使用方法
C标准函数库中,常见的堆上内存管理函数有malloc(), calloc(), recalloc(), free(). 之所以使用堆,是因为栈只能用来保存临时变量.局部变量和函数参数.在函数返回时,自 ...
- Linux C 堆内存管理函数malloc()、calloc()、realloc()、free()详解
C 编程中,经常需要操作的内存可分为下面几个类别: 堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的 堆区(heap):一般 ...
- realloc,malloc,calloc函数的区别
from:http://www.cnblogs.com/BlueTzar/articles/1136549.html realloc,malloc,calloc的区别 三个函数的申明分别是: void ...
- malloc calloc realloc,new区别联系以及什么时候用
三个函数的申明分别是:void* realloc(void* ptr, unsigned newsize);void* malloc(unsigned size);void* calloc(size_ ...
- 【转】【C/C++】内存分配函数:malloc,calloc,realloc,_alloca
转自:http://www.cnblogs.com/particle/archive/2012/09/01/2667034.html#commentform malloc: 原型:extern voi ...
- malloc,calloc,realloc,alloc
三个函数的申明分别是: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(si ...
- C:malloc/calloc/realloc/alloca内存分配函数
原文地址:http://www.cnblogs.com/3me-linux/p/3962152.html calloc(), malloc(), realloc(), free(),alloca() ...
- malloc,calloc,realloc函数用法,原理及不同解析
https://blog.csdn.net/lixungogogo/article/details/50887028 一.malloc malloc在MSDN中原型为: void *malloc( s ...
随机推荐
- 安装Chrome driver/ IE driver
2014-08-15 11:38 22100人阅读 评论(0) 收藏 举报 分类: python基础学习(97) >>>安装Chrome driver chrome driver ...
- idea maven打不了war包
开发的时候打不了war包,原因是 web.xml有问题或者是在idea里面webroot没有作为web引用, 添加之后WebRoot上面有个地球标志 就ok了
- jq重复切换类名
//重复切换类名"active"$(".probability-rules header").toggleClass("active");
- HTML 折行br
HTML 折行 如果您希望在不产生一个新段落的情况下进行换行(新行),请使用 <br /> 标签: <p>This is<br />a para<br /&g ...
- input输入框数字验证
正则限制input只能输入大于零的数字:onkeyup="this.value=this.value.replace(/\D|^0/g,'')" onafterpaste=&quo ...
- Excel Events
WorkbookEvents Interface WorkbookEvents_ActivateEventHandler Delegate WorkbookEvents_AddinInstallEve ...
- markdown中设置、调整图片尺寸
使用百分比描述尺寸 <img src="https://img2018.cnblogs.com/blog/1122471/201902/1122471-2019022218575673 ...
- node-7.2.1 already installed, it's just not linked
直接在terminal下运行以卸载node和nvm: sudo rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,shar ...
- SVN安装操作流程
SVN 安装操作流程 1.服务端安装流程 1.1 双击打开svn-server安装包 1.2 点击Next 1.3 勾选上“I accert the terms in the License Agre ...
- MySQL绿色解压缩版安装与配置
操作步骤: 一.安装MySQL数据库 1.下载MySQL-5.6.17-winx64.zip文件.2.解压到指定目录,本例为D:\mysql-5.6.17-winx64.3.修改配置文件,my-def ...