【发布时间】:2020-09-25 16:58:15
【问题描述】:
这似乎是一个显而易见的问题,但我无法在任何地方明确找到答案。考虑以下代码:
{
std::aligned_storage_t<sizeof(int), alignof(int)> storage;
int& i = *new(&storage) int;
}
在这里,我开始了一个名为i 的对象的生命周期,但是这个生命周期没有明确的“结束”,因为不应该调用~int。
我不确定这个问题的答案是否取决于类型是否微不足道,所以我将提供第二个示例:
class MyMem : public std::pmr::memory_resource
{
std::size_t mem_size = 0u;
char* mem_handle = nullptr;
virtual void* do_allocate(std::size_t bytes, std::size_t) final
{
mem_size += bytes;
mem_handle = static_cast<char*>(std::realloc(mem_handle, mem_size));
return mem_handle + mem_size - bytes;
}
virtual void do_deallocate(void*, std::size_t, std::size_t) final {}
virtual bool do_is_equal(const std::pmr::memory_resource&) const noexcept { return false; }
public:
void* data() const noexcept { return mem_handle; }
};
//...
MyMem mbr;
{
std::aligned_storage_t<sizeof(std::pmr::vector<int>), alignof(std::pmr::vector<int>)> vec_storage;
auto& vec = *new(&vec_storage) std::pmr::vector<int>(&mbr);
vec.resize(N);
}
// Free the data here
std::free(mbr.data());
使用自定义内存资源,我可以获得对vector::resize 调用分配的数据的句柄,并确保我们不会泄漏内存。然而,vector 的实际析构函数调用丢失了,该内存中分配的每个 int 对象的析构函数调用也丢失了。
【问题讨论】:
-
@AsteroidsWithWings 感谢您的链接,非常有趣。我将其解读为,no 没有未定义的行为,因为我不“依赖析构函数产生的副作用”?
-
向量 dtor 可能由于释放而产生副作用。不过我不知道pmr。这基本上意味着只要 dtor 微不足道,您就是安全的。然而,措辞非常模糊,我尽量避免再次猜测它。为什么不直接破坏
-
我想我现在需要定义“任何依赖于析构函数产生的副作用的程序”,我的例子是否依赖于
~vector的副作用?我不会这么说,那样的话就不会有UB。 -
能够“释放”
vector使用的内存对于转移所有权非常有用。
标签: c++ c++17 language-lawyer destructor