与新/删除一起 [英] Overallocating with new/delete

查看:69
本文介绍了与新/删除一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用mallocfree,可以很容易地分配带有多余数据的结构.但是,如何使用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?)

可能没有明显的技术差异,但对我来说newdelete表示正在创建和销毁对象,即使该对象只是一个字符也是如此.当您将字符数组分配为通用块"时,它将使用数组分配器(特别适用于数组)并在其中名义上构造字符.然后,必须使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆