在已释放的unsynchronized_pool_resource上再次调用allocate()是否属于未定义行为?

huangapple go评论191阅读模式
英文:

call allocate() again on the released unsynchronized_pool_resource is an undefined behavior or not?

问题

我目前正在学习unsynchronized_pool_resource的行为。所以我有这个示例代码

std::pmr::monotonic_buffer_resource buffer_resource{std::pmr::new_delete_resource()}; // 从new_delete_resource获取原始内存的单调包装器
std::pmr::unsynchronized_pool_resource midlevel{&buffer_resource}; // 第2个池
std::pmr::unsynchronized_pool_resource un_sync{&midlevel}; // 第3个池
std::pmr::polymorphic_allocator<MyClass> allocator{&un_sync}; // 从第3个池获取内存的分配器

MyClass* t = allocator.allocate(1);
allocator.construct(t, 20);
allocator.destroy(t);

un_sync.release(); // 释放

MyClass* ttt = allocator.allocate(1); // 在已释放的内存资源上再次调用allocate()
allocator.construct(ttt, 40);
allocator.destroy(ttt);

它运行正常,并经过我的测试,似乎第3个池是从第2个池重新构建的。我没有找到任何明确的(或者我没有看到)关于这种行为的信息。所以在已释放的unsynchronized_pool_resource上再次调用allocate()是否属于未定义行为?

英文:

I am currently leaning the behavior of unsynchronized_pool_resource. So I have this sample code

std::pmr::monotonic_buffer_resource buffer_resource{std::pmr::new_delete_resource()}; //monotonic wrapper raw memory get from new_delete_resource
std::pmr::unsynchronized_pool_resource   midlevel{&amp;buffer_resource}; //2nd pool
std::pmr::unsynchronized_pool_resource   un_sync{&amp;midlevel}; //3rd pool
std::pmr::polymorphic_allocator&lt;MyClass&gt; allocator{&amp;un_sync}; //allocator get memory from 3rd pool

MyClass* t = allocator.allocate(1);
allocator.construct(t, 20);
allocator.destroy(t);

un_sync.release(); //release

MyClass* ttt = allocator.allocate(1); //call allocate on released memory resources 
allocator.construct(ttt, 40);
allocator.destroy(ttt);

It works fine, and after my test, it seems like the 3rd pool re-build the pool from the 2nd pool. I didn't find any explicit(or I didn't see) information about this behavior. So call allocate() again on the released unsynchronized_pool_resource is an undefined behavior or not?

答案1

得分: 1

根据我的了解,这应该没问题。

当你执行:

un_sync.release();

这个 release 函数会释放所有内存,但不会丢弃上游资源的指针。根据这里的说明:

> 通过根据需要调用上游内存资源的 deallocate 函数,释放此资源拥有的所有内存。
>
> 即使对一些已分配的块未调用 deallocate,内存也会被释放回上游资源。

因此,这会释放所有内存,但通过调用上游资源的 de-allocate。所以当你执行:

MyClass* ttt = allocator.allocate(1); // 在已释放的内存资源上调用 allocate

这与第一次调用相同,你是在现有的上游上调用 allocate。

英文:

As far as i can tell this should be fine.

When you do:

un_sync.release();

This release function de-allocates all the memory, it doesn't drop the upstream resource's pointer. According to here:

> Releases all memory owned by this resource by calling the deallocate function of the upstream memory resource as needed.
>
>Memory is released back to the upstream resource even if deallocate has not been called for some of the allocated blocks.

So this releases all the memory. But by calling de-allocate of the upstream resource. So when you do:

MyClass* ttt = allocator.allocate(1); //call allocate on released memory resources 

It is the same as the first time, you are calling allocate on the existing upstream.

huangapple
  • 本文由 发表于 2023年3月9日 13:00:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75680593.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定