带有附加字节缓冲区的Allocate_shared
allocate_shared with additional byte buffer
任务:shared_ptr with T=buffer,其中buffer具有动态字节数(末尾为uint8_t[]);
是否allocate_shared保证这个顺序将被保留:[shared_ptr data][object][additional butebuffer]
因为其他方式不起作用,例如:[object][shared_ptr data][add butebuffer]
其他实现思路?
template <class T>
class addon_allocator : public boost::noncopyable
{
public :
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
public :
template<typename U> struct rebind
{
typedef addon_allocator<U> other;
};
public :
explicit addon_allocator( std::size_t size )
:m_size( size )
{
}
~addon_allocator()
{
}
addon_allocator(const addon_allocator<T>& other)
:m_size(other.m_size)
{
}
template <class U>
explicit addon_allocator(const addon_allocator<U>& other)
:m_size(other.get_addon_size())
{
}
pointer address(reference r)
{
return &r;
}
const_pointer address(const_reference r)
{
return &r;
}
pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0)
{
assert( cnt == 1 );
return reinterpret_cast<pointer>(
::operator new(sizeof(T) + m_size)
);
}
void deallocate(pointer p, size_type)
{
::operator delete(p);
}
std::size_t get_addon_size() const
{
return m_size;
}
private:
const std::size_t m_size;
};
class buffer : public boost::noncopyable
{
public:
buffer( std::size_t size )
:m_size(size)
{
}
const std::size_t m_size;
uint8_t m_data[];
static boost::shared_ptr<buffer> create(std::size_t size)
{
boost::allocate_shared<buffer>(
addon_allocator<buffer>(size),
size
);
}
};
你的代码也将与std::allocate_shared
在libstdc++中的实现一起工作,但我不认为有任何保证内存布局将是那样的。
由于您已经有一个用于创建shared_ptr
的特定函数,因此手动进行内存分配比在自定义分配器中使用allocate_shared
更可移植:
class buffer : public boost::noncopyable
{
public:
buffer( std::size_t size ) throw()
:m_size(size)
{
}
const std::size_t m_size;
uint8_t m_data[];
static boost::shared_ptr<buffer> create(std::size_t size)
{
void* addr = ::operator new(sizeof(buffer) + size);
return boost::shared_ptr<buffer>(::new(addr) buffer(size));
}
};
这样就不需要分配器类型,需要维护的代码更少,而且代码都在一个地方。这确实失去了allocate_shared
只进行单个分配的优势(并保持shared_ptr refcounting元数据与对象相邻),但它保证在任何实现上都能工作……这取决于你是否值得。
此代码依赖于buffer
构造函数为无抛出,如果它可以抛出create
函数,则需要捕获异常,释放内存并重新抛出。
我还会考虑将构造函数设为私有,以便buffer
对象只能由create
函数创建。
最后我决定使用:
- boost::intrusive_ptr with T = buffer
- boost::atomic with T = std::size_t用于引用计数(不是boost的一部分,单独的库)
可移植的单分配。
相关文章:
- 模式"allocate memory or use existing data"
- 引用 std::shared:ptr 以避免引用计数
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- 为什么'allocate in one library and free in the other'是错误的
- 无法使用 libtool 将 -shared 参数传递给 g++
- 链接 boost 库时"Error while loading shared libraries"引发的,除了我无法使用 root 访问权限来修复它
- 解决方法:'can not be used when making a shared object; recompile with -fPIC'使用Cmake。使用普通的 g++ 工作
- gcc -fPIC vs. -shared
- 使用 system(命令) 时,C++代码在 AWS 中失败,并出现错误"cannot allocate memory"
- 在shared_from_this()中的错误类型(在继承类中)(是否有dyn.type-ware shared Poi
- 对"cv::String::allocate(unsigned long)"的未定义引用
- "directory containing symbolic versions of my app's shared libraries"的位置(ndk-stack)
- 加载共享库时未定义的符号"tbb internal Allocate"
- Qt自定义插件无法加载 - "Shared Library Not Found"
- C - Shared Library - dlopen, dlsym
- ubuntu 12.04 中的 openCV 程序编译错误"libopencv_core.so.2.4: cannot open shared object file: No such file or
- boost::shared_ptr和std::shared-ptr的同居
- 将GoogleMock与Boost::Shared Pointers一起使用时泄漏的Mock对象
- Singleton: C++ shared dll
- 如何测试分配器是否使用std::allocate进行内存分配