与新/删除一起 [英] Overallocating with new/delete
问题描述
使用malloc
和free
,可以很容易地分配带有多余数据的结构.但是,如何使用new
/delete
完成相同的操作?
Using malloc
and free
, it is easy to allocate structures with extra data beyond the end. But how do I accomplish the same with new
/ delete
?
我知道我可以在分配部分中使用放置新语法以及malloc
,但是如果将对象放置在malloc
分配的内存中,delete
是否可以正常且可移植地工作?
I know I could use placement new syntax along with malloc
for the allocation part, but will delete
work properly and portably if I place an object in memory allocated by malloc
?
我要完成的操作与以下示例相同,但使用的是new
/delete
而不是malloc
/free
,这样可以正确调用构造函数/析构函数:
What I want to accomplish is the same as the following example, but using new
/ delete
instead of malloc
/ free
, so that constructors/destructors will be called properly:
#include <cstdlib>
#include <cstring>
#include <iostream>
class Hamburger {
int tastyness;
public:
char *GetMeat();
};
char *Hamburger::GetMeat() {
return reinterpret_cast<char *>(this) + sizeof(Hamburger);
}
int main(int argc, char* argv[])
{
Hamburger* hb;
// Allocate a Hamburger with 4 extra bytes to store a string.
hb = reinterpret_cast<Hamburger*>(malloc(sizeof(Hamburger) + 4));
strcpy(hb->GetMeat(), "yum");
std::cout << "hamburger is " << hb->GetMeat() << std::endl;
free(hb);
}
输出:hamburger is yum
推荐答案
如果我是你,我将使用new放置和一个显式的析构函数调用,而不是delete
.
If I were you, I'd use placement new and an explicit destructor call instead of delete
.
template< typename D, typename T >
D *get_aux_storage( T *x ) {
return reinterpret_cast< D * >( x + 1 );
}
int main() {
char const *hamburger_identity = "yum";
void *hamburger_room = malloc( sizeof( Hamburger )
+ strlen( hamburger_identity ) + 1 );
Hamburger *hamburger = new( hamburger_room ) Hamburger;
strcpy( get_aux_storage< char >( hamburger ), hamburger_identity );
cout << get_aux_storage< char const >( hamburger ) << '\n';
hamburger->~Hamburger(); // explicit destructor call
free( hamburger_room );
}
当然,这种优化只应在性能分析证明需要之后才能进行. (您真的会这样节省内存吗?这会使调试更加困难吗?)
Of course, this kind of optimization should only be done after profiling has proven the need. (Will you really save memory this way? Will this make debugging harder?)
可能没有明显的技术差异,但对我来说new
和delete
表示正在创建和销毁对象,即使该对象只是一个字符也是如此.当您将字符数组分配为通用块"时,它将使用数组分配器(特别适用于数组)并在其中名义上构造字符.然后,必须使用new位置在这些字符之上构造一个新对象,这本质上是对象别名或双重构造,然后在要删除所有内容时进行双重破坏.
There might not be a significant technical difference, but to me new
and delete
signal that an object is being created and destroyed, even if the object is just a character. When you allocate an array of characters as a generic "block," it uses the array allocator (specially suited to arrays) and notionally constructs characters in it. Then you must use placement new to construct a new object on top of those characters, which is essentially object aliasing or double construction, followed by double destruction when you want to delete everything.
最好使用malloc
/free
避开C ++对象模型,而不要扭曲它以避免将数据作为对象处理.
It's better to sidestep the C++ object model with malloc
/free
than to twist it to avoid dealing with data as objects.
哦,另一种方法是使用自定义的operator new
,但是它可能是蠕虫病毒的罐头,所以我不推荐这样做.
Oh, an alternative is to use a custom operator new
, but it can be a can of worms so I do not recommend it.
struct Hamburger {
int tastyness;
public:
char *GetMeat();
static void *operator new( size_t size_of_bread, size_t size_of_meat )
{ return malloc( size_of_bread + size_of_meat ); }
static void operator delete( void *ptr )
{ free( ptr ); }
};
int main() {
char const *hamburger_identity = "yum";
size_t meat_size = strlen( hamburger_identity ) + 1;
Hamburger *hamburger = new( meat_size ) Hamburger;
strcpy( hamburger->GetMeat(), hamburger_identity );
cout << hamburger->GetMeat() << '\n';
}
这篇关于与新/删除一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!