Does std::make_shared() use custom allocators?

大兔子大兔子 提交于 2019-12-04 16:09:42

问题


Consider this code:

#include <memory>
#include <iostream>


class SomeClass {
public:
    SomeClass() {
        std::cout << "SomeClass()" << std::endl;
    }

    ~SomeClass() {
        std::cout << "~SomeClass()" << std::endl;
    }

    void* operator new(std::size_t size) {
        std::cout << "Custom new" << std::endl;
        return ::operator new(size);
    }

    void operator delete(void* ptr, std::size_t size) {
        std::cout << "Custom delete" << std::endl;
        ::operator delete(ptr);
    }
};



int main() {
    std::shared_ptr<SomeClass> ptr1(new SomeClass);
    std::cout << std::endl << "Another one..." << std::endl << std::endl;
    std::shared_ptr<SomeClass> ptr2(std::make_shared<SomeClass>());
    std::cout << std::endl << "Done!" << std::endl << std::endl;
}

Here is its output:

Custom new
SomeClass()

Another one...

SomeClass()

Done!

~SomeClass()
~SomeClass()
Custom delete

Clearly, std::make_shared() didn't call the new operator -- it's using a custom allocator. Is this the standard behavior for std::make_shared()?


回答1:


Yes, this is standard behavior. From the standard (§20.7.2.2.6 shared_ptr creation ):

Effects: Allocates memory suitable for an object of type T and constructs an object in that memory via the placement new expression ::new (pv) T(std::forward<Args>(args)...).

This allows make_shared to allocate the storage for both the object and the data structure for the shared pointer itself (the "control block") in a single allocation, for efficiency reasons.

You could use std::allocate_shared if you want to control that storage allocation.




回答2:


To expand on Mat's correct answer, make_shared is typically implemented by allocating an object that contains the shared_ptr reference counts and a buffer of uninitialized bytes:

template<typename T>
  struct shared_count_inplace
  {
    long m_count;
    long weak_count;
    typename std::aligned_storage<sizeof(T)>::type m_storage;
    // ...
  };

This is the type which will be allocated on the heap, not your type, so your type's new is not called. Then your type will be constructed using placement new at the location (void*)&m_storage.



来源:https://stackoverflow.com/questions/14080408/does-stdmake-shared-use-custom-allocators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!