new和malloc
1.申请的内存所在位置
自由存储区(free store)是C++基于new操作符的一个抽象概念,凡是new进行内存申请,该内存为自由存储区。堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,malloc函数从堆上动态分配内存,free释放已分配的对应内存。
根据operator new的实现细节,free store不仅可以是堆,还可以是静态存储区。甚至可不为对象分配内存。
new (place_address) type。 place_address为指针代表一块内存地址,此时new调用特殊operator new即:
oid * operator new (size_t,void *) //不允许重定义这个版本的operator new
其只简单返回指针实参,new负责再指定地址进行对象初始化工作。
2.返回类型安全性
new分配内存成功时,返回对象类型的指针,类型严格与对象匹配,无需转换,类型安全(等价内存安全,不会试图访问没授权的内存区域)的操作符。
malloc则返回void *,需要通过强制类型转换将void *指针变成我们需要的类型。
3.内存分配失败时的返回值
new会抛出bac_alloc异常,不返回NULL(malloc返回);习惯在malloc后判断是否成功
int *a = (int *)malloc ( sizeof (int ));
if(NULL == a)
{
...
}
else
{
...
}
4.是否需要制定内存大小
new无须执行,编译器根据类型自行计算,malloc需要显式指出内存尺寸。
class A{...}
A * ptr = new A;
A * ptr = (A *)malloc(sizeof(A)); //需要显式指定所需内存大小sizeof(A);
5.是否调用构造函数/析构函数
new的三步:1、调用operator new函数(对数组是operator new[])分配一块足够大、原始未命名的内存空间来存储对象。2、编译器运行相应构造函数以构造对象,并为其传入初值。3、构造完后返回指定对象的指针。
delete的两步:1、调用对象的析构函数。2、编译器调用operator delete(数组operator delete[])函数内存空间。
malloc的反例:
class A
{
public:
A() :a(), b(1.11){}
private:
int a;
double b;
};
int main()
{
A * ptr = (A*)malloc(sizeof(A));
return ;
}

A的默认构造函数没有被调用,a,b没有被初始化。malloc/free对标准库中凡是需要构造的类型通通不合适!!!
6.对数组的处理
new会分别调用构造函数初始化每一个数组元素,释放对象时为每个对象调用析构函数。
malloc只给你一块内存地址就完事。
7.new与malloc是否相互调用
operator new/operator delete可以基于malloc实现,但反之不行。
void * operator new (sieze_t size)
{
if(void * mem = malloc(size)
return mem;
else
throw bad_alloc();
}
void operator delete(void *mem) noexcept
{
free(mem);
}
8.是否可以被重载
new可以。8个重载版本
//这些版本可能抛出异常
void * operator new(size_t);
void * operator new[](size_t);
void * operator delete (void * )noexcept;
void * operator delete[](void *)noexcept;
//这些版本承诺不抛出异常
void * operator new(size_t ,nothrow_t&) noexcept;
void * operator new[](size_t, nothrow_t& );
void * operator delete (void *,nothrow_t& )noexcept;
void * operator delete[](void *,nothrow_t& )noexcept;
9.直观重新分配内存
malloc分配后若内存不足使用realloc重新分配。realloc先判断当前指针所指的内存是否有足够的连续空间,有则原地扩大返回原本指针,不够新指定空间,拷贝源数据,释放源内存区域。
new没有。
10.客户处理内存分配不足
在operator new抛出异常前会先调new-bandler用户指定的错误处理函数。
namespace std
{
typedef void (*new_handler)();
}
指向了一个没有参数没有返回值的函数(错误处理函数),需要调用set_new_handler,这是一个声明与的标准库函数:
namespace std
{
new_handler set_new_handler(new_handler p ) throw();
}
set_new_handler的参数为new_handler指针,指向了operator new 无法分配足够内存时该调用的函数。其返回值也是个指针,指向set_new_handler被调用前正在执行(但马上就要发生替换)的那个new_handler函数。
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释放掉. ...
随机推荐
- [转] How Bill Gates read books
Bill Gates is one of the most famous figures in the business world. He is one of the richest men in ...
- http/1.0/1.1/2.0与https的比较
HTTP是HyperText Transfer Protocol的缩写,译为超文本传输协议.是一种应用于OSI七层模型中应用层的协议,是我们平常互联网网络通信传输的基础.它的作用就是规定了服务器和客户 ...
- Vue-router的传参方式和router使用技巧
vue传参方法一 1,路由配置 { path: '/describe/:id', name: 'Describe', component: Describe } 2,使用方法 // 直接调用$rout ...
- vue组件的通信
组件的引入两种方式 动态组件 <p is="com-a"></p> 直接引入 <com-a></com-a> 插槽功能 父组件引入 ...
- apk的api级别不要低于26
谷歌要求 api级别 最低26, 在用 xbuliber打包app的时候,可以在 manifest.json增加下面的代码. "plus": { "distribute& ...
- 磁盘挂载方法 fdisk parted
1创建磁盘分区 [root@web01 ~]# fdisk -cu /dev/sdc -c 关闭dos兼容模式-u 使用扇区进行分区 (默认位柱面)[root@web01 ~]# partprobe ...
- kubernetes二进制部署k8s-master集群controller-manager服务unhealthy问题
一.问题现象 我们使用二进制部署k8s的高可用集群时,在部署多master时,kube-controller-manager服务提示Unhealthy [root@ceph-01 system]# k ...
- 【亲测】Asp.net Mvc5 + EF6 code first 方式连接MySQL总结
本文原文地址为:https://www.cnblogs.com/summit7ca/p/5423637.html 原文测试环境为windows 8.1+Vs2013+MySql5.7.12 本人在wi ...
- svn初涉及使用
SVN是为了代码版本控制而生的,为集中式设计. SVN下载 我的为Windows系统,有6种版本SVN可选择,关于选取哪种参见 Windows平台下不同版本SVN对比 我选择了上述博主推荐的 ...
- Java的命名规范
1.类名.接口名:首单词的第一个字母要大写.如果有多个单词,其他单词的首字母要大写. 2.包名:全部小写. 3.变量名.方法名:首单词的第一个字母小写.如果有多个单词,其他单词的首字母要大写. 4.常 ...