void* in malloc vs operator new
void* in malloc vs operator new
今天我为我的代码编写了一个小型内存档案器,并且第一次重载了operator new
。在这样做的过程中,我认为语法是void* operator new(size_t sz)
。这确实与malloc
非常相似,其中有void* malloc(size_t sz)
。
这让我开始思考,因为当你使用malloc
时,你需要显式地将指针投射回你的数据类型,而对于new,你不需要这样做。编译器如何为new
确定正确的数据类型?为什么让返回void *
?T* operator new(size_t sz)
不是更直观吗?
operator new
函数不返回T*
,因为返回的值不指向T
,而只是指向任意垃圾。直到调用构造函数,才有了指向类实例的指针。
C++分离内存分配和对象构造。分配函数(即operator new()
)将void *
返回到某个内存,并且new
运算符在该内存中构造对象。如果你愿意的话,new
操作符将内存"转换"为对象,而placement-new
表达式有点像"cast":
void * addr = ::operator new(sizeof(Foo)); // memory
Foo * p = ::new (addr) Foo(1, true, 'a'); // object (note: no cast!)
p->~Foo(); // it's almost over
::operator delete(addr); // now it's over!
new
的默认非放置表单一次性执行分配和构造。这在道德上相当于这个例子的前半部分。但是,分配和建设仍然是两个截然不同的概念。
operator new
和新运算符之间存在差异。后者创建给定类型的对象,前者只是分配内存。新运算符为正在创建的类型调用operator new
,或者,如果没有为所需类型定义版本,则使用全局operator new
。不能从operator new
函数返回T*
,因为它将指向尚未创建的对象。只有在构造函数运行后(以及任何内务管理,如vtable创建、RTTI信息等),才会创建对象。
不要忘记,您可以为任何类重写operator new
并更改它的行为——它实际上不需要分配任何内存,只需要返回一个指向某些内存的指针。例如,该内存可以来自预先分配的块。
operator new
是new
运算符的一个用户可重写的运行时支持功能,它只提供分配适当对齐和大小的内存块的服务。此函数本身不是new
运算符;当您重写此函数时,并不是在重写new
运算符本身,而只是替换分配服务。new
运算符可以被认为是一个语法糖,它编译成对其助手operator new
的调用,以获取内存,如果需要,还可以调用构造函数来初始化内存。
- 过载'operator new'如何导致无限循环?
- 在C++中调用 malloc() 与"operator new"函数之间的实现差异
- C++和组装:通过ASM呼叫'operator new'和'operator delete'
- 'operator new':函数不接受 2 个参数
- 错误 C2661:'CObject::operator new':没有重载函数需要 4 个参数
- 错误 35 错误 C2661:'operator new':没有重载函数占用 2 个参数
- 什么是"::operator new"和"::operator delete"?
- void* in malloc vs operator new
- 我们还需要"placement new"和"operator new"吗?
- 'operator new'的第一个形式参数必须'size_t'
- 正在对使用operator new okay的放置delete操作的结果调用delete
- operator new[]在MSVC调试时非常慢
- ::operator new[]()与::operator new()有什么不同?
- 为什么替换malloc()需要了解链接器,而::operator new()不需要
- 带nothrow选项的Operator new仍然会抛出异常
- :operator delete(void*)是否知道使用::operator new(size_t)分配的内存大小
- 类x没有默认构造函数,operator new继承
- 如何使用operator new对包含复合类的派生类进行直接初始化
- 如何使用operator new创建动态2D字符数组
- 执行operator new的任何实现都返回指向大小为零的数组的保护页的指针