mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-20 04:02:15 +02:00
Fix ASAN detected new/delete mismatches
The unique_ptr_slab variation of the std::unique_ptr<T> addresses the issue of new/delete mismatches in code that allocates a _memory slab_ with the global _operator_ new but de-allocates an _object_ with a delete _expression_. The use case that manifests the mismatch is as follows: Allocate a slab of memory that has a C struct at the head of the slab, with a "my_type mt[0];" as the head's last member. The slab is cast to the type of the C struct, but sized to contain N my_type items. The object based de-allocation is the behavior of the std::default_delete<T> template; it is used by the std::unique_ptr<T> if the user does not specify an alternative deleter. The unique_ptr_slab resolves the mismatch with an alternative deleter that de-allocates the _memory slab_ with the global _operator_ delete. Signed-off-by: Mark Deric <jmark@openvpn.net>
This commit is contained in:
parent
313426a8cd
commit
6bb4e9c7be
@ -24,10 +24,41 @@
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace openvpn {
|
||||
template<typename T>
|
||||
using unique_ptr_del = std::unique_ptr<T, std::function<void(T*)>>;
|
||||
|
||||
// The unique_ptr_slab variation of the std::unique_ptr<T> addresses the issue of
|
||||
// new/delete mismatches in code that allocates a _memory slab_ with the global
|
||||
// _operator_ new but de-allocates an _object_ with a delete _expression_. The use
|
||||
// case that manifests the mismatch is as follows: Allocate a slab of memory that has
|
||||
// a C struct at the head of the slab, with a "my_type mt[0];" as the head's last
|
||||
// member. The slab is cast to the type of the C struct, but sized to contain N
|
||||
// my_type items.
|
||||
//
|
||||
// The object based de-allocation is the behavior of the std::default_delete<T>
|
||||
// template; it is used by the std::unique_ptr<T> if the user does not specify an
|
||||
// alternative deleter. The unique_ptr_slab resolves the mismatch with an alternative
|
||||
// deleter that de-allocates the _memory slab_ with the global _operator_ delete.
|
||||
template<typename T>
|
||||
void delete_slab(T* ptr) {
|
||||
::operator delete(const_cast<typename std::remove_cv<T>::type*>(ptr));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class slab_deleter
|
||||
{
|
||||
public:
|
||||
slab_deleter() {}
|
||||
void operator()(T* ptr){
|
||||
delete_slab(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using unique_ptr_slab = std::unique_ptr<T, slab_deleter<T>>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user