gpt4 book ai didi

c++ - make_shared 与自定义新运算符

转载 作者:行者123 更新时间:2023-11-30 05:40:06 25 4
gpt4 key购买 nike

这可能是重复的,但我无法在任何地方找到解决方案。

我有这样的源代码:

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_sharedstd::allocate_shared 所以我有 single allocation 而不是两次分配?


更新

我能够消除 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);

它做的事情完全一样,但我想现在我想做的事情更清楚了。

最佳答案

这是得出的结论。

由于无法将大小传递给分配器,您可以通过全局变量类成员来传递。

在这两种情况下,解决方案都一点也不优雅,而且相当危险 - 灾难等待现在或以后需要维护代码时发生。

如果 allocate_sharedshared_ptr 控制 block 放在缓冲区类的之后,则可能会发生另一个意想不到的问题。

在这种情况下会出现明显的缓冲区溢出,因为 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 %p\n", b.get());

printf("%s\n", b->x);
printf("%zu\n", b.use_count());
auto b1 = b;
printf("%zu\n", b1.use_count());

return 0;
}

关于c++ - make_shared 与自定义新运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31904439/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com