Fix broken detached storage ownership in gtl::vector extensions#50
Conversation
34f69d9 to
6340eae
Compare
|
I found that |
|
Oh, I forgot to update tests. I'll fix that. |
|
Hi @zhao-shihan , thank you for the great PR. Please leave the |
Hi @greg7mdp! Fixed in 962aca0. |
|
|
||
| // ------------------- gtl extensions ------------------------------------------------------- | ||
| struct detached_storage_deleter { | ||
| allocator_type alloc; |
There was a problem hiding this comment.
shouldn't this be allocator_type &alloc here, so we use the same allocator instance to deallocate the detached storage as the one that allocated it and was passed in the detached_storage_ptr to the constructor at line 745. In essence the vector created with this special constructor should continue using the same allocator instance that was used to allocate the buffer I think. This is to address the case of stateful allocators.
Well, it is more complicated than that, but I think we can't just assume that creating a new allocator is acceptable in all cases. Maybe we need to have alternative constructors for detached_storage_deleter , including one that takes a rvalue for the allocator.
There was a problem hiding this comment.
Still this PR is better than the previous code. Maybe we can merge this and address remaining issues later. I am travelling and I can't investigate this as well as I'd like.
There was a problem hiding this comment.
I think here shouldn't be an allocator reference because
- After
steal_data, the vector turns into a "null" state and can be deconstruted. If so, the allocator instance is also deconstruted and the allocator reference will dangling. - A reference member makes the deleter not default constructible, and this also propagates to the unique_ptr, which is not very easy to use.
Here, when the deleter is constructed, only the allocator is copied instead of the whole vector::Impl. I think copy the allocator is OK because all sane allocators passed to a container are stateless (because the standard API not plays well with stateful allocators, e.g. vector constructor copys an allocator, and vector::get_allocator also returns a copy of the allocator).
Actually here detached_storage_deleter can be more compact by marking alloc as [[no_unique_address]], since stateless allocators often have no data members. For example, std::allocator.
There was a problem hiding this comment.
Still this PR is better than the previous code. Maybe we can merge this and address remaining issues later. I am travelling and I can't investigate this as well as I'd like.
OK, just take your time. It's not urgent.
6216a01 to
621ea67
Compare
|
Thanks again @zhao-shihan ! |
Summary
This PR fixes two critical issues in the gtl vector ownership-transfer extensions and makes detached storage deallocation allocator-correct.
Files Changed
Problem Statement
What Changed
Behavioral and Safety Impact
Breaking Change Note
This change is API-breaking for two gtl extensions (constructor and steal_data return type).
However, the previous API was already functionally broken and unsafe. Therefore, the project should choose one of these two directions:
Migration Notes
Callers using the previous unique_ptr-based extension API should migrate to detached_storage_ptr and detached_storage_deleter so deallocation remains allocator-correct.