所以这是一个有点奇怪的问题,但是如果我有一个类,它的全部目的是通过保存一个指向分配内存的分配器的指针来删除它自己:
struct SelfDeleter
{
std::pmr::memory_resource* m_allocator;
void delete_self()
{
m_allocator->deallocate(this, sizeof(SelfDeleter), alignof(SelfDeleter));
}
};
然后我们运行它:
int main()
{
std::pmr::memory_resource* resource = std::pmr::get_default_resource();
SelfDeleter* obj = reinterpret_cast<SelfDeleter*>(resource->allocate(sizeof(SelfDeleter), alignof(SelfDeleter)));
obj->m_allocator = resource;
obj->delete_self();
return 0;
}
这样做安全吗?我知道为了调用释放函数,m_allocator的值将被加载到寄存器中,但我最担心的是编译器可能会在稍后丢弃该值,然后在释放函数期间尝试从堆上的m_allocator再次加载它,而该值可能已被删除。
我试过运行这段代码,它看起来很有效,但我不确定这是否完全是巧合。我知道我可以通过使用std::launder强制将m_allocator复制到堆栈中,从而确保值不会从堆中重新加载,但我不确定我是否必须这样做以保证安全行为。显然,在释放后再次访问指针是不安全的,但对于这个问题,我只关心对释放函数的调用
1条答案
按热度按时间kcrjzv8t1#
我认为,这是一个正确的实现。在单线程应用程序上,没有意外的副作用。最大的问题是,你的用例是什么?如果你想要更健壮的代码:在解除分配对象之前将内存清零会有很大帮助。