1

Closed

Default deleter for unique_ptr used on malloc'd memory

description

In Samples\CaseStudies\NBody\NBodyAdvancedCpu.cpp in the function GetLevelOneCacheSize, there is the variable:
std::unique_ptr<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(nullptr);
Which is later assigned to:
buffer = std::unique_ptr<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>((PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(bufferSize));
The default deleter is used here, which will call delete on the given pointer. That is, this is roughly equivalent (memory management-wise) to:
void* ptr = malloc(8);
delete ptr; // undefined behavior, was not allocated with new
The type of the bufferSize variable should be changed to use a custom deleter, probably something like this:
template <typename T>
struct free_deleter
{
    free_deleter() throw() // noexcept in C++11
    {}

    template <typename U>
    free_deleter(const free_deleter<U>&,
                 typename std::enable_if<std::is_convertible<U*, T*>::value,
                                         void>::type** = nullptr) throw()
    {}

    void operator()(T* const ptr) const throw()
    {
        static_assert(std::has_trivial_destructor<T>::value,
                      "Cannot free memory for a type with a non-trivial destructor, use delete.");

        std::free(ptr);
    }
};
Giving:
typedef std::unique_ptr<SYSTEM_LOGICAL_PROCESSOR_INFORMATION,
                        free_deleter<SYSTEM_LOGICAL_PROCESSOR_INFORMATION>> buffer_type;
buffer_type buffer(nullptr);

// ...

buffer = buffer_type((PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(bufferSize));
This will correctly use free on the malloc'd memory (and will prevent wrong usage with a type that needs delete). I have not looked elsewhere in the code for other places malloc'd memory is delete'd.
Closed Feb 25, 2013 at 4:42 AM by AdeMiller
Thanks for picking up on this. Very careless of me. I've looked for other explicit uses of malloc() in the samples and couldn't find any.

I've fixed this with changeset 101831.

comments