malloc与new,free与delete

复制代码
malloc,free是一种库函数,不能被重载,new和delete是运算符,可以被重载
new和delete内部都调用malloc和free函数

new的三种用法:
1.new,不可以被重载
    直接new一个对象
    T* ptr = new T();
    new一个对象时做了两件事情
* 调用了operator new申请空间
* 调用了构造函数,如果括号中为空,会调用默认构造函数

2.operator new,可以被重载
    重载形式:
    必须为void* operator new(size_t n, . . .); 
    行为类似于malloc,就是申请一段空间
    重载后new一个对象会调用这个函数

3.placement new
    原地构造一个对象,相当于显示调用构造函数
    new (T*) T(args);
使用方式如下:
    A *pointer = (A*)malloc(sizeof(A));
    new(pointer)A(10);
    cout << pointer->i << endl;



delete:类似于new
会首先调用析构函数析构,然后调用free()释放空间
可以被重载,重载形式如下:
    void operator delete(void* ptr, . . .);

new[]:
首先调用operator new[]申请n段连续的T空间,然后会调用n次默认构造函数,可以被重载
重载形式如下:
    void* operator new[](size_t n, . . .);
如果重载了此函数,new[]会调用这个函数

delete[]:
与new[]配套使用,会先调用n次析构函数,然后再释放空间,可以被重载
重载形式如下:
    void operator delete[](void* ptr, . . .);
如果重载了此函数,delete[]会调用这个函数。

测试代码:
#include
<iostream> using namespace std; class A { public: A() : i(1) { cout << "A default constructor" << endl; } A(int j) : i(j) { cout << "A constructor" << endl; } ~A() { cout << "A destructor" << endl; } int i; }; class B { public: B() : i(1) { cout << "B default constructor" << endl; } B(int j) : i(j) { cout << "B constructor" << endl; } ~B() { cout << "B destructor" << endl; } void* operator new(size_t n){ cout << "B my new" << endl; B* p = (B*)malloc(n); return p; } void* operator new[](size_t n){ cout << "B my new[]" << endl; B* p = (B*)malloc(n * sizeof(B)); return p; } void operator delete(void* ptr){ cout << "B my delete" << endl; free(ptr); } void operator delete[](void* ptr){ cout << "B my delete[]" << endl; free(ptr); } int i; }; int main() { //---------------------------A---------------------------// A *ptr_A_1 = new A; cout << ptr_A_1->i << endl; delete ptr_A_1; cout << endl; A *ptr_A_2 = new A(); cout << ptr_A_2->i << endl; delete ptr_A_2; cout << endl; A *ptr_A_3 = new A(2); cout << ptr_A_3->i << endl; delete ptr_A_3; cout << endl; A *ptr_A_4 = new A[3]; auto p = ptr_A_4; for(int i = 0; i < 3; ++i) cout << (p + i)->i << " "; cout << endl; delete[] ptr_A_4; cout << endl; //------------------------B-------------------------// B *ptr_B_1 = new B; cout << ptr_B_1->i << endl; delete ptr_B_1; cout << endl; B *ptr_B_2 = new B(); cout << ptr_B_2->i << endl; delete ptr_B_2; cout << endl; B *ptr_B_3 = new B(2); cout << ptr_B_3->i << endl; delete ptr_B_3; cout << endl; B *ptr_B_4 = new B[3]; auto p1 = ptr_B_4; for(int i = 0; i < 3; ++i) cout << (p1 + i)->i << " "; cout << endl; delete[] ptr_B_4; cout << endl; return 0; }

复制代码
posted @ 2017-12-18 11:19  CoderZSL  阅读(249)  评论(0)    收藏  举报
编辑推荐:
· 为什么说方法的参数最好不要超过4个?
· C#.Net 筑基-优雅 LINQ 的查询艺术
· 一个自认为理想主义者的程序员,写了5年公众号、博客的初衷
· 大数据高并发核心场景实战,数据持久化之冷热分离
· 运维排查 | SaltStack 远程命令执行中文乱码问题
阅读排行:
· 博客园众包平台:诚征3D影像景深延拓实时处理方案(预算8-15万)
· 发布一个小功能,通过 markdown 图片语法嵌入B站视频
· 《HelloGitHub》第 111 期
· 谷歌新AI工具杀疯了?免费,但有点坑!Gemini CLI 抢先实测
· Spring AI Alibaba 1.0 正式发布!核心特性速览+老项目升级指南
点击右上角即可分享
微信分享提示