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释放掉. ...
随机推荐
- wholesale custom weighted blankets / travel weighted blankets
What is weighted blankets? Weighted blanket named heavy gravity blanket,for child and adult. Help re ...
- Oracle中查看SQL语句的索引命中情况及CPU占用
第一种: 在PL/SQL中,在Explain plan Window中执行要优化的Sql语句.结果,如下图: Object name列中显示了命中的索引名,Cost列显示了CPU的使用率(%). 第二 ...
- sqlserver常用存储过程基本语法
一.定义变量--简单赋值 declare @a intset @a=5 print @a --使用select语句赋值 declare @user1 nvarchar(50) select @user ...
- hive常用操作
相关显示参数设置 显示参数设置 set hive.cli.print.header=true; // 打印列名 set hive.cli.print.row.to.vertical=true; // ...
- ceph版本号
概述 第一个 Ceph 版本是 0.1 ,要回溯到 2008 年 1 月.多年来,版本号方案一直没变,直到 2015 年 4 月 0.94.1 ( Hammer 的第一个修正版)发布后,为了避免 0. ...
- vim常用指令
命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim ...
- inout口在modelsim仿真的方法
//主要是// 和**********部分是关键 1 `timescale 1ns/1ns module tb(); reg main_clk; :] addr; reg FPGA_CS0;//FPG ...
- Linux下数据库备份
1.登录数据库服务器并切换到数据库用户下 [root@*** ~]# su - oracle 2.测试用户名密码是否能正确连接数据库 [oracle@*** ~]$ sqlplus username/ ...
- 强行画页面的position
说到position这个属性,确实是让刚入前端坑的我等小白瑟瑟发抖,大牛们一边告诉我们position如何万能,一边又让我们在这个坑里滚了一遍又一遍,着实让我们的头皮表面的毛囊扩张的更厉害了.在前端的 ...
- change the version of python on my centos
There are two versions of aconda: aconda and aconda3 in my home directorys. When comment the environ ...