使用new/delete进行分配

por*_*uod 8 c++ memory-management new-operator

使用mallocfree,很容易为结构分配超出最终的额外数据.但我如何用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

Pot*_*ter 2

如果我是你,我会使用放置 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)

当然,这种优化只能在分析证明有必要之后才进行。(这样真的能节省内存吗?这会让调试变得更困难吗?)

可能没有显着的技术差异,但对我来说,newdelete表明一个对象正在被创建和销毁,即使该对象只是一个角色。当您将字符数组分配为通用“块”时,它会使用数组分配器(特别适合数组)并理论上在其中构造字符。然后,您必须使用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)