c++ - 过度分配新/删除

标签 c++ memory-management new-operator

使用mallocfree,可以很容易地分配超出末尾的额外数据结构。但是如何使用 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/

相关文章:

c# - 将指向 DWORD 的指针从 C# 传递到 C++ DLL

c++ - Unresolved inclusion 错误 eclipse

c++ - boost::dynamic_properties 和不可变图形对象

c - 用户空间中的物理内存管理?

c++ - 在存储可以用不同派生类型初始化的基类型成员变量时避免使用 new

c++ - alignas 说明符是否与 'new' 一起使用?

c++ - 如何在宏中使用 vsprintf/vsnprintf?

c - *** 检测到 glibc *** : free(): invalid next size (fast) in C code

iphone - 为什么 Cocoa 偶尔会返回一个空字符串?

c++ - 在 C++ 中实现 placement new 的正确方法