Make_shared与自定义的新操作符
make_shared with custom new operator
这可能是重复的,但我在任何地方都找不到解决方案。
我有这样的源代码:
struct Blob{
//...
static void *operator new(size_t size_reported, size_t size) {
return ::operator new(size);
}
};
我这样使用它:
std::shared_ptr<Blob> blob;
// ...
size_t size = calcSize(); // it returns say 231
Blob *p = new(size) Blob();
blob.reset(p);
我能不能改变代码,让我可以使用std::make_shared
或std::allocate_shared
,这样我就有了single allocation
而不是two allocations
?
更新
我能够消除new
并将代码简化为以下内容:
struct Blob{
//...
};
std::shared_ptr<Blob> blob;
// ...
size_t size = calcSize(); // it returns say 231
// allocate memory
void *addr = ::operator new(size);
// placement new
Blob *p = ::new(addr) Blob();
blob.reset(p);
它做完全相同的事情,但我认为现在更清楚我要做什么
我是这么想的
由于没有办法将大小传递给分配器,您可以通过global variable
或class member
来实现。
在这两种情况下,解决方案一点也不优雅,而且相当危险——当代码需要维护时,灾难随时可能发生。
如果allocate_shared
将shared_ptr
控制块放在缓冲区类之后,可能会发生另一个意想不到的问题。在这种情况下,将有明确的缓冲区溢出,因为sizeof(buffer)
将报告大小为1字节左右。
再次-代码正在工作,但将来肯定会有问题。
#include <stdio.h>
#include <string.h>
#include <memory>
// ============================
class buffer{
public:
buffer(const char *s){
strcpy(x, s);
}
char x[1];
};
// ============================
template <typename T>
struct buffer_allocator {
using value_type = T;
buffer_allocator() = default;
template <class U>
buffer_allocator(const buffer_allocator<U>&) {}
T* allocate(size_t n) {
void *p = operator new(n * sizeof(T));
printf("Allocate %p, (%zu)n", p, get_size());
return (T*) p;
}
void deallocate(T* p, size_t n) {
delete p;
printf("Deallocate %p, (%zu)n", p, get_size());
}
size_t get_size(){
return size;
}
void set_size(size_t size){
this->size = size;
}
private:
size_t size = 0;
};
template <typename T, typename U>
inline bool operator == (const buffer_allocator<T>&, const buffer_allocator<U>&) {
return true;
}
template <typename T, typename U>
inline bool operator != (const buffer_allocator<T>& a, const buffer_allocator<U>& b) {
return !(a == b);
}
// ============================
int main(int argc, char *argv[]){
buffer_allocator<buffer> ba;
const char *s = "hello world!";
ba.set_size( strlen(s) + 1 );
auto b = std::allocate_shared<buffer>(ba, s);
printf("Pointer %pn", b.get());
printf("%sn", b->x);
printf("%zun", b.use_count());
auto b1 = b;
printf("%zun", b1.use_count());
return 0;
}
相关文章:
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- C++自定义比较函数
- 如何比较自定义类的std::变体
- std::设置自定义比较器
- 重载自定义类集的提取操作符
- 操作符new已在带有库的自定义内存管理器中定义
- 自定义迭代器操作符重载
- 将facet应用于所有流输出,使用自定义字符串操作符
- 在b树的自定义迭代器中使用操作符*出错
- 重载c++实类型和自定义复杂类型之间的强制转换操作符()
- CUDA应用程序的自定义类int2_, float2_和double2_之间的重载操作符=
- 唯一/shared_ptr自定义操作符=
- 重载& lt; & lt;用于打印自定义异常的操作符
- Make_shared与自定义的新操作符
- 一个自定义的向量和矩阵类在c++和操作符[]
- 重载自定义栈实现中的==操作符
- 如何在不重载比较操作符的情况下为std::max专门化自定义类型
- 自定义复制赋值操作符使程序崩溃(c++)
- 操作符的算法重载-用于自定义整数类