前言

在使用腾讯云对象存储c++ sdk的时候,发现了分段下载api一个bug。由于不同平台的 std::vector 实现不一样,在windows平台分段下载的时候会触发崩溃。

原因:std::vector 调用 clear()之后,vector 的 size 设置为 0,再通过 []下标方式访问访问 vector 的时候触发 out-of-bound。在linux平台则不会触发。这是由于不同平台的stl模板库实现不一致导致的。

解决办法: 调用 clear方法后,调用 resize 方法重新设置 vector 的 size,再通过下标方式访问 vector 就不会崩溃。

vec_offset.clear();					// 调用 clear清理 vector之后 把size设置成0,capacity不变。不会释放vector内存
vec_offset.resize(pool_size);		// 重新设置vector的大小
vec_offset[task_index] = offset;	// 通过下标访问vector 就不会崩溃

windows VC平台下 std::vector operator[] 的实现

在windows平台下VC环境,通过 operator[] 获取数组元素,会检查下标有效性。如果vector 的size是0 会抛出 out of range异常。

	reference operator[](size_type _Pos)
		{	// subscript mutable sequence
 
 #if _HAS_ITERATOR_DEBUGGING
		if (size() <= _Pos)
			{
			_DEBUG_ERROR("vector subscript out of range");
			_SCL_SECURE_OUT_OF_RANGE;
			}
 #endif /* _HAS_ITERATOR_DEBUGGING */
		_SCL_SECURE_VALIDATE_RANGE(_Pos < size());
 
		return (*(_Myfirst + _Pos));
		}

Linux平台下 std::vector operator[] 的实现

Linux 环境下通过operator[] 获取数组元素,不会检查下标有效性。

      // element access
      /**
       *  @brief  Subscript access to the data contained in the %vector.
       *  @param n The index of the element for which data should be
       *  accessed.
       *  @return  Read/write reference to data.
       *
       *  This operator allows for easy, array-style, data access.
       *  Note that data access with this operator is unchecked and
       *  out_of_range lookups are not defined. (For checked lookups
       *  see at().)
       */
      reference
      operator[](size_type __n)
      { return *(this->_M_impl._M_start + __n); }

总结

在使用 std::vector 的时候如果调用了clear 清空函数后,再次通过 [] 下标访问 vector 元素时候注意检查 vector 的 size是否有效。这样写出的代码才能更好的跨平台。


技术参考

  1. 视频技术参考: https://ke.qq.com/course/3202131?flowToken=1041285
  2. 关于 std::vector 的下标越界检查:https://blog.csdn.net/luansxx/article/details/10194171
  3. vector.clear()不能用来清零内存:https://blog.csdn.net/weixin_33725126/article/details/93176493
  4. cos cpp sdk 修复了向量越界导致的崩溃: https://github.com/tencentyun/cos-cpp-sdk-v5/pull/80
Logo

更多推荐