SGISTL源码-分配器 笔记

Allocator

从实现的角度来看,配置器是一个实现了动态空间配置、空间管理、空间释放的 class template。

defalloc.h

标准的空间分配器。只是实现了基层的分配、释放行为(operator newoperator delete封装),并没有进行优化

allocate/deallocate

基础的分配、释放函数,只是简单的封装了一下operator newoperator delete

template <class T>
inline T* allocate(ptrdiff_t size, T*) {
    set_new_handler(0);   // 为了卸载目前的内存分配异常处理函数,强制C++在内存不够的时候抛出std:bad_alloc。
    // 申请size个T类型大小的空间
    T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
    if (tmp == 0) {
        cerr << "out of memory" << endl; 
        exit(1);
    }
    return tmp;
}
template <class T>
inline void deallocate(T* buffer) {
    ::operator delete(buffer);
}
class allocator
pointer allocate(size_type n) { 
    return ::allocate((difference_type)n, (pointer)0);
}//分配空间,调用上面封装后的函数
void deallocate(pointer p) { ::deallocate(p); }
pointer address(reference x) { return (pointer)&x; }	//获取地址
const_pointer const_address(const_reference x) { 
    return (const_pointer)&x; 
}
size_type init_page_size() { 
    return max(size_type(1), size_type(4096/sizeof(T))); 
}
size_type max_size() const { 
    return max(size_type(1), size_type(UINT_MAX/sizeof(T))); 
}

stl_construct.h

在上述基础上,对对象的构造和析构进行了一定的封装。

construct

构造函数除基本的调用外无重要的点。基本调用的函数为inline void _Construct(_T1* __p, const _T2& __value) { new ((void*) __p) _T1(__value); }

destroy

首先调用萃取机判断是否有析构函数,然后根据反馈分别调用相应的函数。

typedef typename __type_traits<_Tp>::has_trivial_destructor _Trivial_destructor;
// 若是 __true_type,什么都不做;这是 trivial destructor。
template <class _ForwardIterator> 
inline void __destroy_aux(_ForwardIterator, _ForwardIterator, __true_type) {}

// 若是 __false_type,这才以循环的方式遍历整个范围,并在循环中每经历一个对象就调用其destory()。(内部调用析构函数)
// 这是 non-trivial destructor
template <class _ForwardIterator>
void __destroy_aux(_ForwardIterator __first, _ForwardIterator __last, __false_type)
{
    for ( ; __first != __last; ++__first)
        destroy(&*__first);
}

此外,还有一些特化版本(非类,无需过多特殊处理):

inline void _Destroy(char*, char*) {}
inline void _Destroy(int*, int*) {}
inline void _Destroy(long*, long*) {}
inline void _Destroy(float*, float*) {}
inline void _Destroy(double*, double*) {}

stl_uninitialized.h

该部分用于copy、fill大块内存中存储的数据。同样的

uninitialized_copy

该函数实现copy功能,首先调用萃取机判断是否是POD(传统 旧 数据)数据类型 typedef typename __type_traits<_Tp>::is_POD_type _Is_POD;,然后根据返回的结果调用不同的函数 return __uninitialized_copy_aux(__first, __last, __result, _Is_POD());。传统旧数据无需过多操作,直接复制即可。否则,循环调用相应的函数进行构造。

template <class _InputIter, class _ForwardIter>
inline _ForwardIter __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
                         _ForwardIter __result,
                         __true_type)
{
    return copy(__first, __last, __result);
}

template <class _InputIter, class _ForwardIter>
_ForwardIter  __uninitialized_copy_aux(_InputIter __first, _InputIter __last,
                         _ForwardIter __result,
                         __false_type)
{
    _ForwardIter __cur = __result;
    __STL_TRY {
        for ( ; __first != __last; ++__first, ++__cur)
            _Construct(&*__cur, *__first);
        return __cur;
    }
    __STL_UNWIND(_Destroy(__result, __cur));
}
uninitialized_fill

该函数与上述函数同理,所使用的is_POS_type及相关处理策略也相同,再此不赘述。

__uninitialized_copy_copy

该函数实现两个范围的拷贝,即为调用两次uninitialized_copy函数。函数源码如下:

template <class _InputIter1, class _InputIter2, class _ForwardIter>
    inline _ForwardIter
    __uninitialized_copy_copy(_InputIter1 __first1, _InputIter1 __last1,
                              _InputIter2 __first2, _InputIter2 __last2,
                              _ForwardIter __result)
{
    _ForwardIter __mid = uninitialized_copy(__first1, __last1, __result);
    __STL_TRY {
        return uninitialized_copy(__first2, __last2, __mid);
    }
    __STL_UNWIND(_Destroy(__result, __mid));
}

所实现的功能为拷贝两次。在result位置,先插入第一个范围,再在新的位置继续插第二个范围。即:

  1. 首先将 [ f i r s t 1 , l a s t 1 ) \left[first1,last1\right) [first1,last1)数据拷贝到
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 最新的SGI STL源码可以从以下几个渠道进行下载。 首先,你可以在GitHub上找到SGI STL的官方仓库。在该仓库中,你可以浏览并下载最新的源代码文件。GitHub提供了多种形式的下载选项,你可以选择下载整个仓库的压缩文件(zip格式),或者直接克隆仓库到本地。 其次,你还可以访问SGI STL的官方网站,该网站上提供了SGI STL的下载链接。进入官方网站后,你可以查看可供下载的最新版本,然后选择所需的版本进行下载。官方网站通常会提供详细的文档和说明,帮助你更好地使用和理解SGI STL源码。 此外,你还可以通过搜索引擎查找其他第三方网站或平台上提供的SGI STL源码下载链接。这些网站也可能提供最新版本的下载选项,但请注意检查源码的可靠性和合法性。 无论你选择哪种方式下载SGI STL源码,建议先仔细阅读相关文档,理解源码的结构和使用方法,以便更好地应用和扩展SGI STL库。 ### 回答2: 最新的SGI STL源码可以通过以下方式进行下载: 1. 访问SGI官方网站:SGI(STL)是由Silicon Graphics Inc.开发的,可以在其官方网站上找到最新的源码下载链接。可以使用搜索引擎来查找SGI官方网站,并在网站上查找STL源码的下载链接。 2. 在Github上搜索:Github是一个开源代码托管平台,许多开发者会将他们的代码上传到这个平台上。在Github上,你可以搜索SGI STL,并找到与STL相关的仓库。浏览相关仓库,找到最新版本的STL源码并进行下载。 3. 使用相关的开发者论坛和社区:在许多专门的开发者论坛和社区中,你可以找到你所需要的开发资源。参与这些论坛,提出你的需求,寻求帮助并询问最新的SGI STL源码下载途径。其他开发者可能会分享他们的经验和提供相应的下载链接。 4. 前往开发者相关的网站:有一些开发者网站会提供各种开发资源的链接和下载。搜索一些开发者网站,并检查他们所提供的STL源码下载选项。 总之,要下载最新的SGI STL源码,你可以通过访问SGI官方网站、使用Github进行搜索、参与开发者论坛和社区或前往开发者相关的网站来获取下载链接。确保你下载的是经过验证的可靠源码,并在你的项目中合理使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值