C++在指定内存构造对象

栏目: C++ · 发布时间: 6年前

内容简介:为了提高程序的性能,一个做法是一次性分配足够多的内存,从而避免多次申请以及数据拷贝。对于c++,有一个问题:如何在已分配好的内存上构造对象?前文“有两种解决方案解决这个问题。

问题

为了提高程序的性能,一个做法是一次性分配足够多的内存,从而避免多次申请以及数据拷贝。对于c++,有一个问题:如何在已分配好的内存上构造对象?

前文“ vector的性能利器:reserve ”提到使用 reserve 预先分配内存,再 push_backemplace_back ,存储过万个大对象时可极大提升效率。探究其实现原理,会发现分配内存简单,调用标准库或者 nedmalloctcmalloc 等库中的函数即可;有了内存,问题同样变成如何在已分配的内存上构造对象?

方案

有两种解决方案解决这个问题。

placement new

第一种方案是使用 placement new 。其用法过程为:首先分配足够大的内存;然后用 placement new 语法生成对象: new(ptr) xxx() ,其中 ptr 是足够容纳所指对象的指针。

一个使用例子:

class Person {
private:
  int age;
  std::string name;
public:
  // methods
};

int main(int argc, char** argv) {

  char mem[sizeof(Person)]; // 或者 auto mem = malloc(sizeof(Person));

  auto p = new(mem) Person();

  assert((void*)p == (void*)mem); // 两个指针指向同一块内存

  return 0;
}

使用 placement new 有三个注意点:一是要有足够的内存放置对象,这是必须的;二是指针应该是“对齐”的,例如对于4字节对齐的系统,指针地址应该是4的整数倍;三是你(可能)需要显式调用析构函数完成对象的销毁。

operator new

使用 new 生成对象实际上执行了三个操作:

operator new

其中 operator new 是可重载的,无论全局还是特定类。其函数原型为:

void* operator new(size_t sz);

回到把对象在指定内存上构造的问题上,我们可以通过重载 operator new ,返回已分配内存的指针。然而由于 operator new 函数只接受一个参数,地址指针需要是“全局”变量才能生效。这样想来,这种方案实用性并不高。

其他

如果你希望像vector中的 reserve 先分配内存,然后在其上装载对象,可以使用 allocatorallocator 定义在 头文件中,能对指定类型分配合适的内存,并可手动调用对象的构造函数和析构函数。

用法示例:

int main(int argc, char** argv) {
  std::allocator<Person> alloc;
  auto p = alloc.allocate(1); // 分配一个Person对象的内存
  alloc.construct(p);   // 调用Person的构造函数,如果构造函数有参数,参数写在p之后
  // p 现在是一个指向Person的指针,且其指向对象被初始化过
  // 对p进行一些操作

  // 销毁对象,但不释放内存,等同于调用p->~Person()
  alloc.destroy(p);
  // 释放内存
  alloc.deallocate(p, 1);
  return 0;
}

对于可以内部管理的情形,建议使用 allocator 而非 placement new

作用

为什么有这个需求呢?个人觉得有三方面的原因:

reserve

参考

  1. https://stackoverflow.com/questions/519808/call-a-constructor-on-a-already-allocated-memory
  2. https://isocpp.org/wiki/faq/dtors#placement-new

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pattern Recognition and Machine Learning

Pattern Recognition and Machine Learning

Christopher Bishop / Springer / 2007-10-1 / USD 94.95

The dramatic growth in practical applications for machine learning over the last ten years has been accompanied by many important developments in the underlying algorithms and techniques. For example,......一起来看看 《Pattern Recognition and Machine Learning》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

html转js在线工具
html转js在线工具

html转js在线工具