c++ - shared_ptr 中的可变大小对象

标签 c++ arrays memory-management smart-pointers

假设我想要一个可变大小的数组,其中有一些标题预先存储在 std::shared_ptr 中。我可以做类似的事情

#include <memory>
using namespace std;
struct obj {
  char headerCode;
  unique_ptr<short[]> data;
};
shared_ptr<obj> make(unsigned len) {
  return shared_ptr<obj>{new obj{'x', unique_ptr<short[]>{new short[len]}}};
}

但这会导致三种分配:一种用于shared_ptr 控制 block ,一种用于obj,另一种用于其data。使用 make_shared 前两个共享一些内存是可能的:

#include <memory>
using namespace std;
struct obj {
  char headerCode;
  unique_ptr<short[]> data;
  obj(char headerCode, short data[]) : headerCode(headerCode), data(data) {}
};
shared_ptr<obj> make(unsigned len) {
  return make_shared<obj>('x', new short[len]);
}

通过低级分配,我可以让对象和它的数据共享一些内存:

#include <memory>
#include <cstdlib>
using namespace std;
struct obj {
  char headerCode;
  short data[0];
};
shared_ptr<obj> make(unsigned len) {
  obj* o = reinterpret_cast<obj*>(malloc(sizeof(obj) + len*sizeof(short)));
  o->headerCode = 'x';
  return shared_ptr<obj>(o, free);
}

标准允许使用这两种技术吗?如果不是,是否有类似的东西是允许的?有没有什么东西可以让这项工作以符合标准的方式进行,只需要一次内存分配?最好不必在每个实例中都存储分配器或删除器对象?

最佳答案

Are these two techniques allowed by the standard?

第一个很好,第二个使用零长度数组作为成员 (data[0]),这不是有效的 C++,但作为扩展被某些编译器支持。

Is there something which makes this work in a standards-conforming way with only a single memory allocation?

目前没有 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3641.html 是相当困难的这将允许这样的事情:

struct obj {
  char headerCode;
  short* data;
};

shared_ptr<obj> make(unsigned len) {
  auto p = make_shared<char[]>(sizeof(obj) + sizeof(short)*len));
  short* s = static_cast<short*>(p.get() + sizeof(obj));
  return shared_ptr<obj>(p, ::new(p.get()) obj{'x', s});
}

这分配了一个 char 数组,其中有足够的空间用于 objshort 数组,然后使用 placement new 构造一个 obj 到该内存中,并创建另一个 shared_ptr ,它与拥有 char 数组的那个共享所有权。当拥有内存的最后一个 shared_ptr 删除其引用时,char 数组将被正确删除,但 obj 对象的析构函数将不会运行,因此,重要的是您不要依赖其具有任何副作用的析构函数(理想情况下它将具有一个微不足道的析构函数)。

您今天可以使用带有自定义分配器的 allocate_shared 来做到这一点,该分配器为 short 数组分配额外的空间,但是由于您不知道实现会将控制 block 和您的对象安排在分配的空间中,很难找出 short 数组的开始位置,分配器需要存储在控制 block 中。

关于c++ - shared_ptr 中的可变大小对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29452423/

相关文章:

c++ - 在条件下更新变量的最快方法是什么?

c++ - Linker cannot find qwebp lib - 静态Qt5.3.2编译

c++ - 如何从 QTextEdit 中检索单个字符?

C++ 指针数组参数

C++ 什么时候在堆上分配还是在堆栈上分配?

java - 热点 JVM 数组分配

安卓 : How can I know how much memory is allocated on VM for my app?

c++ - Win32API : How to request embedded windows event notifications out to a parent window

c++ - 为什么bool变量不能设置为0,除了直接赋0?

javascript - 将数字添加到 'click' 上的数组