【发布时间】:2015-04-04 23:14:02
【问题描述】:
假设我想要一个可变大小的数组,前面有一点头存储在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);
}
标准是否允许这两种技术?如果没有,是否有类似的东西是允许的?有没有什么东西可以使这项工作以符合标准的方式工作,只需要一个内存分配?最好不必在每个实例中都存储分配器或删除器对象?
【问题讨论】:
-
为什么要使用
reinterpret_cast将void*转换为obj*? -
@JonathanWakely:没有明确转换我的
g++说error: invalid conversion from ‘void*’ to ‘obj*’ [-fpermissive]。但你是对的,static_cast在这里可能更合适。 -
是的,当然不会隐式转换,但是
reinterpret_cast是个大锤,这里没必要。static_cast就足够了。
标签: c++ arrays memory-management smart-pointers