new与malloc
首先将new与malloc的区别总结如下:
1 new可以自动计算需要分配多大的内存,而malloc必须指明。
2 new返回的指针是有类型的,malloc返回void*类型的指针。
3 new在分配内存的同时会调用构造函数。
4 new是c++运算符,malloc是标准库函数。
由于3所述,malloc在c++中无法满足为非内部对象分配内存的需求。
那么malloc是如何进行内存分配的呢?它将内存块连接为一个链表。调用malloc函数时,它沿链表寻找一个大到足以满足用户请求所需要的空闲内存块。然后,将该内存块传给用户(如果该内存块比用户申请的内存大很多,可进行分割),并将该内存块标记为已用。(free的过程待补充)
malloc具体实现参考:
http://blog.codinglabs.org/articles/a-malloc-tutorial.html
该文对Linux系统内存相关知识的介绍也十分清楚。现将其malloc实现简单总结如下:
内存按块划分,每个块由meta区和数据区组成,meta区记录数据区的大小、是否空闲并指向下一个内存块。数据区是真实分配的内存,malloc返回给用户的就是数据区的首地址。首先定义表示内存块的数据结构:
typedef struct s_block* t_block;
struct s_block
{
size_t size;
int free;
t_block next;
int padding;
char data[]; };
然后实现查找内存块的find_block,传入需要分配的内存大小,返回找到的指向内存块的指针:
t_block find_block(t_block* last, size_t s)
{
t_block b = first_block;
while (b&&!(b->free && b->size >= s))
{
*last = b;
b = b->next;
}
return b;
}
从头开始搜索链表,对于不符合条件的节点,last立即跟踪,遇到符合条件的节点或空节点循环结束。last是为了当遍历完链表没有符合条件的节点,即b=NULL时,记录最后一个节点,方便后面做扩展。做扩展的代码如下:
#define BLOCKSIZE 24
t_block extend_block(t_block last, size_t s)
{
t_block b = sbrk();
if (sbrk(s + BLOCKSIZE) == (void*)-)
return NULL;
b->size = s;
b->free = ;
b->next = last->next;
last->next = b;
return b;
}
即用系统调用sbrk()在堆上新找到个节点,并将其接到原链表。malloc还要做的一个工作就是如果内存块比较大,将其分给一个申请了很小内存空间的用户会显得很浪费,此时malloc应将该内存块分割,将剩余的内存作为新节点放在链表上:
void split_block(t_block b, size_t s)
{
t_block newb;
newb = (t_block)b->data + s;
newb->size = b->size - s - BLOCKSIZE;
newb->free = ;
newb->next = b->next;
b->next = newb;
b->size = s;
}
有了以上的函数,malloc就可以简单的实现如下:
void* first_block=NULL; void* malloc(size_t size)
{
size_t s;
s = align(size);
t_block b=first_block;
t_block last;
if (b)
{
b = find_block(&last, s);
if (b)
{
if (b->size >= (s + BLOCKSIZE + ))
split_block(b, s);
b->free = ;
}
else
{
b = extend_block(last, s);
}
}
else
{
b = extend_block(NULL, s);
first_block = b; }
return b;
}
new与malloc的更多相关文章
- malloc 与 free函数详解<转载>
malloc和free函数详解 本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...
- C 语言中 malloc、calloc、realloc 和free 函数的使用方法
C标准函数库中,常见的堆上内存管理函数有malloc(), calloc(), recalloc(), free(). 之所以使用堆,是因为栈只能用来保存临时变量.局部变量和函数参数.在函数返回时,自 ...
- 以冒泡排序为例--malloc/free 重定向stdin stdout
esort.c 代码如下,可关注下mallloc/free,freopen重定向的用法,排序为每轮将最小的数放在最前面: #include<stdio.h> #include<mal ...
- 内存动态分配之realloc(),malloc(),calloc()与new运算符
1,malloc与free是C/C++的标准库函数,new/delete是C++的运算符,是C++面向对象的特征,它们都可用于申请动态内存和释放内存.2,对于非内部数据类型的对象而言,光用maloc/ ...
- 在dll里malloc/new/cvCreate分配内存,在exe里free/Releases释放内存时会出错。
写了个程序,在DLL中用malloc分配了一块内存,但是在exe程序中释放,结果程序crash,原因就是:其原因可能是堆被损坏,这也说明 TestMySticker.exe 中或它所加载的任何 DLL ...
- Linux C 堆内存管理函数malloc()、calloc()、realloc()、free()详解
C 编程中,经常需要操作的内存可分为下面几个类别: 堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的 堆区(heap):一般 ...
- malloc与new的区别
1.new是运算符,而malloc是库函数 2.new可以重载,可以自定义内存分配策略,甚至不做内存分配,甚至分配到非内存设备上.而malloc不能. 3.new在用于定义一个新的非内部对象的时候,默 ...
- new 等于 malloc加构造函数
1.new 是c++中的操作符,malloc是c 中的一个函数 2.new 不止是分配内存,而且会调用类的构造函数,同理delete会调用类的析构函数,而malloc则只分配内存,不会进行初始化类成员 ...
- 关于malloc函数的动态分配问题
malloc函数动态分配了一个整型的内存空间,让abc都指向刚申请的空间,所以只有最后一个赋值语句的值保留在了空间里 #include<stdio.h> main() { int *a,* ...
- 转:如何实现一个malloc
如何实现一个malloc 转载后排版效果很差,看原文! 任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉. ...
随机推荐
- CSS3 动画实现 animation 和 transition 比较
在 CSS3 中有两种方式实现动画, 分别是 animation 和 transition, 他们都有以下功能 根据特定 CSS 属性进行动画 设定属性变化的 timing function 设定动画 ...
- UITableViewCell重用导致内容混乱方案
UITableViewCell *cell=nil; static NSString *reuse=@"cell"; if (cell==nil) { cell=[[UITable ...
- NHibernate系列文章二十三:NHibernate查询之Criteria查询(附程序下载)
摘要 上一篇文章介绍了NHibernate HQL,他的缺点是不能够在编译时发现问题.如果数据库表结构有改动引起了实体关系映射的类有改动,要同时修改这些HQL字符串.这篇文章介绍NHibernate面 ...
- python中的goto
python中没有像C语言中的goto,不过,查找着之后发现有python大牛写了一个goto,我直接拿来用啦,在此分享下: 代码地址:https://github.com/snoack/python ...
- 使用VideoToolbox硬编码H.264<转>
文/落影loyinglin(简书作者)原文链接:http://www.jianshu.com/p/37784e363b8a著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. ======= ...
- 4中map遍历的方法
public static void main(String[] args) { Map<String, String> map = new HashMap<String, Stri ...
- iOS7——UIControlEventTouchDown延迟响应问题
问题描述 在iOS7下开发,真机调试时,UIButton的其他事件响应都正常,但是UIControlEventTouchDown事件响应会延迟,而且不同响应区域发生的延时情况不同,有时延迟1s以后响应 ...
- 使用openssl实现ECDSA签名以及验证功能(附完整测试源码)
突然找到数年前写的这段代码,当是因为对密码学几乎不怎么了解踩了一些坑,现在开源出来方便大家直接利用. ECDSA的全名是Elliptic Curve DSA,也就是椭圆曲线DSA,由于椭圆曲线的复杂性 ...
- 使用github参与开源项目
github上有很多非常优秀的开源项目,作为开源项目的受益者,你否想过为开源项目贡献自己的代码?
- 转: windows下面安装Python和pip终极教程
原文: http://www.cnblogs.com/yuanzm/p/4089856.html 因为如果是初学者在windows环境下安装,简直是折磨人,会遇到各种蛋疼的情况.本文希望提供傻瓜式的教 ...