1

I am using a C framework (DPDK) which provides its own memory management facilities. Now I want to encapsulate these special pointers in an unique_ptr, which requires using a custom deleter (invoking the de-allocation function of the framework). To produce these pointers, I want to implement a factory function similar to make_unique.

I succeed in implementing this for non-array types, but fail for doing it for arrays:

template<typename T>
struct HugepageDeleter {
    void operator()(T* b) { rte_free(b); }
};

template< typename T > using unique_hugepage = std::unique_ptr<T, HugepageDeleter<T>>;

/// std::make_unique for single objects
template<typename T, typename... Args>
unique_hugepage<T> make_unique_hugepage(Args&&... args)
{
    void *ptr = rte_malloc(nullptr, sizeof(T), alignof(T));
    auto t = new (ptr) T(std::forward<Args>(args)...);
    return unique_hugepage<T>(t);
}

template<typename T>
unique_hugepage<T>
make_unique_hugepage_array(size_t num)
{
    void *ptr = rte_malloc(nullptr, sizeof(std::remove_extent_t<T>[num]), alignof(T));
    return unique_hugepage<std::remove_extent_t<T>[]>((std::remove_extent_t<T> *)ptr);
}


int test() {
    unique_hugepage<int> p = make_unique_hugepage<int>();
    auto testData = make_unique_hugepage_array<unsigned char[]>(16000);
}

Compiler output:

/usr/include/c++/10/bits/unique_ptr.h:612:17: error: no match for call to ‘(std::unique_ptr<unsigned char [], HugepageDeleter<unsigned char []> >::deleter_type {aka HugepageDeleter<unsigned char []>}) (unsigned char*&)’
  612 |    get_deleter()(__ptr);
      |    ~~~~~~~~~~~~~^~~~~~~

/.../HugepageMemory.h:14:10: note: candidate: ‘void HugepageDeleter<T>::operator()(T*) [with T = unsigned char []]’
   14 |     void operator()(T* b) { rte_free(b); }
      |          ^~~~~~~~
/.../HugepageMemory.h:14:24: note:   no known conversion for argument 1 from ‘unsigned char*’ to ‘unsigned char (*)[]’
   14 |     void operator()(T* b) { rte_free(b); }
      |                     ~~~^

I am using an zero-size struct as deleter, so that the unique_ptr can remain a zero-cost abstraction.

  • 1
    See also [How to construct unique_ptr(specialization for arrays)?](https://stackoverflow.com/questions/72313478/how-to-construct-unique-ptrt-dspecialization-for-arrays) – Jason Nov 22 '22 at 09:04

0 Answers0