簡體   English   中英

shared_ptr中的可變大小對象

[英]Variable-size object in shared_ptr

假設我想要一個可變大小的數組,該數組的頭先存儲在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控制塊,一種分配給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);
}

標准允許使用這兩種技術嗎? 如果沒有,是否有類似的東西被允許? 是否有某種東西可以僅通過一次內存分配就以符合標准的方式使之工作? 最好不必在每個實例中都存儲分配器或刪除器對象?

標准允許使用這兩種技術嗎?

第一個很好,第二個使用零長度數組作為成員( data[0] ),該成員不是有效的C ++,但某些編譯器支持將其作為擴展。

是否有某種東西可以僅通過一次內存分配就以符合標准的方式使之工作?

當前,如果沒有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與足夠的空間obj和陣列short ,然后使用放置新構建一個obj到該內存,並創建另一個shared_ptr這股所有權與擁有該一個char陣列。 當擁有內存的最后一個shared_ptr刪除其引用時, char數組將被正確刪除,但是obj對象的析構函數將不會運行,因此,請不要依賴於其析構函數具有任何副作用(理想情況下,它將具有瑣碎的破壞者)。

您可能能夠今天用做allocate_shared與分配的數組額外的空間自定義分配器short ,但因為你不知道的實施將如何安排控制模塊,並在空間的對象分配它給相當困難找出short數組從哪里開始,分配器需要存儲在控制塊中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM