[英]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.