自定义内存分配器:T*指针,运算符new与void指针强制转换
Custom memory allocator: T* pointer, operator new versus void pointer cast
我根据gamedev.net文章中的代码创建了一些自定义内存分配器。
文章中描述的一个实用程序模板是这样声明的:
template <class T> T* allocateNew(Allocator& allocator, T& t) {
return new (allocator.allocate(sizeof(T), alignof(T))) T(t);
}
*我将__alignof()
转换为对alignof()
的调用,因为我使用的是C++11
我认为这段代码为新的T
对象分配内存,将t
堆栈对象从引用复制到新分配的堆内存,并返回指向新对象的T*
指针。
有了这个假设,我将上面的代码转换为:
template <class T> T* allocateNew(Allocator& allocator, T& t) {
void *ptr = allocator.allocate (sizeof (T), alignof (T));
assert(ptr && "So that I don't dereference a null pointer");
* (T *) (ptr) = instance; // Casting void* to T* and then dereferencing
return (T *) ptr;
}
它似乎运行得很好。我的问题是:
new
与空指针强制转换有什么不同吗- 两者在性能上有什么不同吗?在G++中,我找不到任何显著的速度差异
- 第二个代码示例是否有任何漏洞(除了我用断言检查的潜在空指针取消引用之外)
问候,TM3P
new与void指针铸造有什么不同吗?
是;它构造了一个新的对象,而不是试图分配给一个实际上并不存在的对象。
两者在性能上有什么不同吗?
对于琐碎的类型,初始化和赋值实际上是一回事,所以可能没有什么区别。对于非平凡类型,它们调用不同的用户定义函数(构造函数与赋值运算符),这可能会做非常不同的事情。
第二个代码示例是否存在任何漏洞?
对于非平凡类型,赋值运算符可能会在赋值前对对象的状态进行假设,如果没有有效的对象,则可能会出现严重错误,使程序陷入未定义的行为。
tl;dr放置新作品,不可靠的选角是不好的。
第一个版本使用placement new在新分配的内存中复制构造对象。这是将原始byes转换为对象的正确、定义明确的方法。
您的版本将字节视为已经是一个对象(通过强制转换),然后为该对象分配一个新值,从而产生未定义的行为。如果T
是一个非常简单的类型,这可以,但不会比第一个版本快。如果该类型有赋值运算符,那么它将出现非常严重的错误。
相关文章:
- 在将 new 与指针一起使用时,创建数组的指定长度
- 在C++中,如果我可以直接将整数分配给指针而不使用"new",为什么要使用"new"?
- 传递给放置 new 的指针是否是指向其对象表示形式的非 UB 指针?
- 删除使用 new 创建的 2D 或 3D 指针
- 基类指针:在哪里使用 new 和 delete
- 双指针在使用 new 时不调用对象构造函数
- 'new'和'='与指针的区别
- 哪些资源是由智能指针管理的,而它们的内存不是由new分配的
- (C++)如何在不导致 mem 泄漏的情况下将指针传递到分配了'new'的函数?
- C++:为什么可以在没有事先使用 new 的情况下在指向结构的指针上使用 delete?
- 为什么运算符"new"需要指针才能工作?
- 将指针返回使用New创建的数组数组
- "new"不会将内存分配给作为类的数据成员的指针
- 带"new"的指针和带"&variable"的指针有什么区别
- 基于索引的 alloca 返回的指针访问和"placement new"的效果
- 将内存分配给 2D 数组时,“new int*[rowCount];”的含义是什么?是 2D 数组,是指向数组的指针数组
- 使用 new: "potentially uninitialized pointer"将对象数组动态分配给指针
- 使用 malloc 而不是 new 会导致 free():指针错误无效
- 如何将一系列指针分配给Usinig New
- 奇怪的c++指针new / delete问题