STLport源代码中的一个BUG

本文分析了STLport实现中的一个潜在错误,涉及`copy`算法在处理指针类型时可能因多重继承导致的指针值变化问题。作者通过示例程序展示了如何触发该错误,并对比了VS2008自带STL的正确实现。建议用户避免在存在类型转换的指针之间使用STLport的`copy`和`uninitialized_copy`算法。
摘要由CSDN通过智能技术生成

STLport是世界上使用最广泛的开源STL实现,很多人通过学习STLport源代码来了解STL中的实现细节。

STLport中的copy算法用于将一个容器中指定范围的元素拷贝到另一个容器中。它是这么实现的(原始代码中有很多编译宏隔离,为了表述方便,只展开预编译选项中有效的代码,下同):

// _algobase.h
template <class _InputIter, class _OutputIter>
inline _OutputIter copy(_InputIter __first, _InputIter __last, _OutputIter __result) 
{
  _STLP_DEBUG_CHECK(_STLP_PRIV __check_range(__first, __last))
  return _STLP_PRIV __copy_aux(__first, __last, __result, _BothPtrType< _InputIter, _OutputIter>::_Answer());
}

这里是想在编译期根据迭代器的不同类型,选择调用不同的函数。_BothPtrType模板判断copy的参数是否都是指针类型,如果是,就会调用这个函数版本:

// _algobase.h
template <class _InputIter, class _OutputIter>
inline _OutputIter __copy_aux(_InputIter __first, _InputIter __last, _OutputIter __result,
                              const __true_type& /*BothPtrType*/) 
{
  return _STLP_PRIV __copy_ptrs(__first, __last, __result,
                                _UseTrivialCopy(_STLP_VALUE_TYPE(__first, _InputIter),
                                                _STLP_VALUE_TYPE(__result, _OutputIter))._Answer());
}

这里又做了一次分发,依据的是_UseTrivialCopy模板。如果模板返回__true_type,就会调用下面这个函数:

// _algobase.h
template <class _InputIter, class _OutputIter>
inline _OutputIter __copy_ptrs(_InputIter __first, _InputIter __last, _OutputIter __result,
                               const __true_type& /*IsOKToMemCpy*/) 
{
  return (_OutputIter)_STLP_PRIV __copy_trivial(__first, __last, __result);
}

inline void* __copy_trivial(const void* __first, const void* __last, void* __result) 
{
  size_t __n = (const char*)__last - (const char*)__first;
  return __n ? (void *)((char*)memmove(__result, __first, __n) + __n) : __result;
}

省事了,直接用memmove代替for循环来完成元素拷贝。这是STL的一大优点:根据参数的类型选择性能最优的操作方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值