por*_*uod 8 c++ memory-management new-operator
使用malloc和free,很容易为结构分配超出最终的额外数据.但我如何用new/ 完成相同的操作delete?
我知道我可以使用放置新语法以及malloc分配部分,但delete如果我将一个对象放在由分配的内存中,它将正常工作并且可移植malloc吗?
我想要完成的是与以下示例相同,但使用new/ delete而不是malloc/ free,以便正确调用构造函数/析构函数:
#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);
}
Run Code Online (Sandbox Code Playgroud)
输出: hamburger is yum
如果我是你,我会使用放置 new 和显式析构函数调用而不是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 );
}
Run Code Online (Sandbox Code Playgroud)
当然,这种优化只能在分析证明有必要之后才进行。(这样真的能节省内存吗?这会让调试变得更困难吗?)
可能没有显着的技术差异,但对我来说,new这delete表明一个对象正在被创建和销毁,即使该对象只是一个角色。当您将字符数组分配为通用“块”时,它会使用数组分配器(特别适合数组)并理论上在其中构造字符。然后,您必须使用placement new 在这些字符之上构造一个新对象,这本质上是对象别名或双重构造,然后当您想要删除所有内容时进行双重销毁。
最好使用malloc/避开 C++ 对象模型free,而不是扭曲它以避免将数据作为对象处理。
哦,另一种选择是使用 custom operator new,但它可能会很麻烦,所以我不推荐它。
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';
}
Run Code Online (Sandbox Code Playgroud)