首页 > 其他分享 >new、::operator new与placement new的区别

new、::operator new与placement new的区别

时间:2023-09-30 19:22:04浏览次数:32  
标签:调用 placement test 类内 operator new delete

在内存管理中,::operator new()/::operator delete() 、delete/new、 placement new 是不同的:

::operator new():只是进行空间的申请而不调用构造函数,可以理解为只是对 malloc 的简单封装,返回 void* 。可以进行类内重载或者全局重载,类内没有重载则寻找全局new。

::operator delete():类似,只是对空间进行释放,而不调用析构函数,可以理解为是对 free 的简单封装。可以类内重载或者全局重载,类内没有重载则寻找全局delete。

new:分为三个步骤:

  1. 调用 ::operator new(sizeof(type)) 申请空间(首先查找类内的 ::operator new() )
  2. 调用 type->constructor 对申请的对象进行构造
  3. 返回对应的指针类型 type*

delete:同new,分为三个步骤:

  1. 调用对应的 type->destroy 进行析构(首先查找类内的 ::operator new() )
  2. 调用 ::operator delete(type*) 进行空间释放
  3. return
//类内重载new、delete
#include<string>
class test {
public:
	
	void* operator new(size_t n) {
		std::cout << "分配了" << n << "bytes" << std::endl;
		return malloc(n);
	}

	void operator delete(void* ptr) {
		std::cout << "释放内存" << std::endl;
		free(ptr);
	}

	test() {
		std::cout << "constructor" << std::endl;
	}
	void sayHello() {
		std::cout << text << std::endl;
	}

	~test() {
		std::cout << "destroy" << std::endl;
	}
private:
	std::string text = "hello world";
};

template<class T1,class T2>
void constructor(T1* ptr, const T2& value) {
	new(ptr)T1(value);
}

int main() {
	test* t2 = new test();
	delete t2;
}
//全局重载new、delete
void* operator new(size_t n) {
	std::cout << "分配" << n << "个bytes" << std::endl;
	return malloc(n);
}

void operator delete(void* p) {
	free(p);
}

#include<string>
class test {
public:
	test() {
		std::cout << "constructor" << std::endl;
	}
	void sayHello() {
		std::cout << text << std::endl;
	}

	~test() {
		std::cout << "destroy" << std::endl;
	}
private:
	std::string text = "hello world";
};

int main() {
	test* t1 = (test*)::operator new(sizeof(test));
	//t1->sayHello();//未初始化,打印失败
	t1->test::test();
	t1->sayHello();
	t1->~test();
	::operator delete(t1);
}

placement new:布局new,比较特殊的一种new,用于在已分配的内存上创建对象,不申请另外的空间,但是需要手动调用析构函数。在内存池中就可以看到对于 placement new 的使用了。

使用placement new的例子:

#include<string>
class test {
public:
	test() {
		std::cout << "constructor" << std::endl;
	}
	void sayHello() {
		std::cout << text << std::endl;
	}

	~test() {
		std::cout << "destroy" << std::endl;
	}
private:
	std::string text = "hello world";
};

template<class T1,class T2>
void constructor(T1* ptr, const T2& value) {
	new(ptr)T1(value);
}

int main() {
	char* buf = (char*)::operator new(sizeof(test) * 2);
	std::cout << (void*)buf << std::endl;	//打印buf地址
	//((test*)buf)->sayHello();//未初始化buf,打印出现问题
	constructor((test*)buf, test());
	std::cout << (void*)buf << std::endl;	//再次打印buf地址,没有改变
	((test*)buf)->sayHello();//已初始化,打印hello world
	((test*)buf)->~test();//手动析构对象
	delete buf;
}

小小总结:

真正申请和释放内存空间其实是在 ::operator new(size_t) 中调用 malloc() 和在 ::operator delete() 中调用 **free() **,构造函数和析构函数并不会申请或释放内存空间。而placement new不调用malloc,而是在已分配的内存上创建对象。

标签:调用,placement,test,类内,operator,new,delete
From: https://www.cnblogs.com/MyJyang/p/17738131.html

相关文章

  • 创建商品价格修改记录表 new创建修改时间
    createtableprice_log(  idintnotnullauto_incrementprimarykey,  product_idintunsignednotnull,   pricedecimal(10,2),  create_timetimestampnotnulldefaultcurrent_timestamp,  update_timetimestampnotnulldefaultcurrent_......
  • Python:operator模块
    methodcaller:调用参数指定的方法,实例方法和类方法都可以;04.Python冷知识:你可能不知道的三个操作符-itemgetter,attrgetter,methodcaller_哔哩哔哩_bilibilifromoperatorimportitemgetter,attrgetter,methodcallerprint("下面演示itemgetter用法:")get_index_zero=......
  • Hugging News #0925: 一览近期的新功能发布
    每一周,我们的同事都会向社区的成员们发布一些关于HuggingFace相关的更新,包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等,我们将其称之为「HuggingNews」。本期HuggingNews有哪些有趣的消息,快来看看吧!......
  • UE4之NewObject方法
    template<classT>T*NewObject(UObject*Outer,FNameName,...){...FStaticConstructObjectParametersParams(T::StaticClass());Params.Outer=Outer;Params.Name=Name;...returnstatic_ca......
  • 【C++】动态内存管理 ⑤ ( 基础数据类型数组 内存分析 | 类对象 内存分析 | malloc 分
    文章目录一、基础数据类型数组内存分析1、malloc分配内存delete释放内存2、new分配内存free释放内存二、类对象内存分析1、malloc分配内存delete释放内存2、new分配内存free释放内存博客总结:C语言中使用malloc分配的内存,使用free进行释放;C++语言中......
  • C#中使用Newtonsoft.Charp实现Json对象序列化与反序列化
    场景C#中使用Newtonsoft.Json实现对Json字符串的解析:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/105795048上面讲的对JSON字符串进行解析,实际就是JSON对象的反序列化。在与第三方进行交互时常需要封装对象,存储各种属性消息,然后将对象序列化为json字符串并进......
  • OGG报错 INS-85054 in oggca.sh createing a new Service Manager after removing a p
    这个报错主要是ogg的自启动和目录问题DeletethefollowingfilesattheOSlevel:Linux7/etc/systemd/system/OracleGoldenGate.service/etc/oggInst.locLinux6/etc/init.d/OracleGoldenGate/etc/rc.d/*OracleGoldenGate/etc/rc*.d/*OracleGoldenGate/etc/oggInst......
  • CF1106D Lunar New Year and a Wander 题解
    CF1106D题解暑期学校军训第一天模拟赛的题,相对而言比较简单题意:题意其实很简单,就是有一个无向图,需要你从\(1\)号节点出发,然后一次遍历所有的点,输出其中字典序最小的遍历思路说说思路吧,这题既然要遍历图上所有点,那首先就会想到\(\texttt{BFS}\)或\(\texttt{DFS}\),可本题还......
  • Hugging News #0918: Hub 加入分类整理功能、科普文本生成中的流式传输
    每一周,我们的同事都会向社区的成员们发布一些关于HuggingFace相关的更新,包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等,我们将其称之为「HuggingNews」。本期HuggingNews有哪些有趣的消息,快来看看吧!......
  • JavaScript-实例对象与 new 命令
    对象是什么 面向对象编程(ObjectOrientedProgramming,缩写为OOP)是目前主流的编程范式。它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。每一个对象都是功能中心,具有明确分工,可以完成接受信息、处理数据、发出信息等任务。对象可以......