boost :: make_shared底层对象和引用计数对象的内存分配大小在哪里?

时间:2014-06-08 00:32:39

标签: c++ memory-management boost shared-ptr make-shared

我试图了解boost::make_shared如何为boost::shared_ptr和引用计数对象(shared_ptr使用)管理的对象进行内存分配。

make_shared函数在这里开始执行:

template< class T, class A1, class A2, class A3 >
typename boost::detail::sp_if_not_array< T >::type make_shared( A1 && a1, A2 && a2, A3 && a3 )
{
    //Seems to create the smart_ptr for the object
    boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );

    //Not sure?
    boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );

    //Calculates the address at which the bulk-allocation begins
    void * pv = pd->address();

    //Allocates the memory at address pv?
    ::new( pv ) T(
        boost::detail::sp_forward<A1>( a1 ), 
        boost::detail::sp_forward<A2>( a2 ), 
        boost::detail::sp_forward<A3>( a3 )
        );

    //Not sure
    pd->set_initialized();

    //Not sure
    T * pt2 = static_cast< T* >( pv );

    //Not sure
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
    return boost::shared_ptr< T >( pt, pt2 );
}

有人能够帮助解释其余的线路吗?

我正在尝试确定大容量内存分配的大小(指向 shared_ptr引用计数对象的对象)的确定位置?

让我感到震惊的是,在分配要分配的地址时,对address()的调用似乎没有考虑T对象的大小。

(我真的不明白输入方法的三个AX参数是什么,并传递给展示位置new()

1 个答案:

答案 0 :(得分:4)

让我们逐行采取行动

  boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );

这会创建共享指针,但这里的键是删除器。 BOOST_SP_MSD(T)是一个宏,它解析为具有足够额外空间的删除器。因此共享指针引用计数块还包括删除器的空间,该空间现在包括T

的空间
    //Not sure?
    boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );

这从共享指针获取删除器地址。这将指向上面创建的删除器。

    //Calculates the address at which the bulk-allocation begins
    void * pv = pd->address();

这将返回类型T的起始地址,该地址当前未初始化并且是删除者的一部分

    //Allocates the memory at address pv?
    ::new( pv ) T(
        boost::detail::sp_forward<A1>( a1 ), 
        boost::detail::sp_forward<A2>( a2 ), 
        boost::detail::sp_forward<A3>( a3 )
        );

这是一个新的展示位置。这会在T中提供的地址构建您的pv。它传递了3个参数,因为这是make_shared的3-arg版本。

    //Not sure
    pd->set_initialized();

这是删除器中的一个内部标志,它让它知道T已被构造(这样当调用删除器operator()时,它会将其销毁)< / p>

    //Not sure
    T * pt2 = static_cast< T* >( pv );

这将上面的void *转换为T*。老实说,我不确定为什么他们只是没有保留新位置的结果。

    //Not sure
    boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );

这是提供enable_shared_from_this功能所必需的。此内部函数为enable_shared_from_this设置基础机制。当您将某些内容放入shared_ptr

时,通常会调用它
    return boost::shared_ptr< T >( pt, pt2 );

这实际上会创建一个新的boost::shared_ptr,它使用与pt相同的引用计数区域,但其get()和相关方法将返回pt2,这是指针到T,存储在删除器中。