使用malloc
和free
,可以很容易地分配超出末尾的额外数据结构。但是如何使用 new
/delete
完成相同的操作?
我知道我可以将 placement new 语法与 malloc
一起用于分配部分,但是如果我将一个对象放入由 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);
}
输出:hamburger is yum
最佳答案
您可以在不求助于 malloc/free 或未定义行为的情况下执行此操作(我不确定 reinterpret_cast,但至少可以很好地完成构建/销毁)。
要分配内存,您可以直接调用全局 operator new。之后,您使用良好的旧放置新来在那里构造对象。不过,您必须保护 ctor 调用,因为如果 ctor 失败时调用的“放置删除”函数不会释放任何内存,而只是什么也不做(就像放置新的什么都不做一样)。
要在之后销毁对象,您可以(并且可能)直接调用析构函数,并释放内存,您可以调用全局运算符 delete。
我认为像删除任何普通对象一样删除它也应该没问题,因为之后调用析构函数和全局运算符 delete 正是普通删除所做的,但我不是 100% 确定。
你的例子修改成这样:
#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 space for a Hamburger with 4 extra bytes to store a string.
void* space = operator new(sizeof(Hamburger) + 4);
// Construct the burger in that space
hb = new (space) Hamburger; // TODO: guard ctor call (release memory if ctor fails)
strcpy(hb->GetMeat(), "yum"); // OK to call member function on burger now
std::cout << "hamburger is " << hb->GetMeat() << std::endl;
// To delete we have to do 2 things
// 1) call the destructor
hb->~Hamburger();
// 2) deallocate the space
operator delete(hb);
}
关于c++ - 过度分配新/删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5520591/