You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时需关注数组偏移量溢出?同尺寸索引与偏移类型安全性探讨

同尺寸无符号索引与有符号偏移量的溢出安全性分析

当数组偏移量类型与索引类型的sizeof相同时,是否需要关注偏移量值的溢出问题?

从直观角度看,有符号偏移量的取值范围仅为无符号索引的一半,当偏移量超过索引寻址范围的一半时会发生溢出,但结合C++标准的相关条款,我们可以得出更准确的结论:

C标准3.9.1.4条款:无符号整数需遵循模2ⁿ算术法则(n为该整数的值表示位数)
C
标准5.3.1.8条款:无符号量的负值通过将其值从2ⁿ中减去计算(n为提升后操作数的位数)

基于上述标准,使用同尺寸的无符号类型作为索引、有符号类型作为偏移量在以下操作场景中是安全的:

  • 索引与偏移量相加
  • 根据计算得到的新索引获取元素
  • 比较两个计算得到的索引

注:暂不涉及两个偏移量的比较,这属于另一种需要单独分析的场景。

以下代码可验证这一结论:

#include <iostream>
#include <limits>

using index_t = unsigned int;
using offset_t = signed int;

int main()
{
    index_t index = 100;
    const offset_t extra_offset = 1000;

    offset_t offset_large = std::numeric_limits<offset_t>::max() + extra_offset; // 形式上偏移量发生溢出

    long long int output_convestion;

    index_t position_large = index + offset_large;
    output_convestion = position_large;

    long long int position = index;
    position += std::numeric_limits<offset_t>::max();
    position += extra_offset;

    std::cout << "Position large = " << output_convestion << "  should be = " << position <<
        (output_convestion == position ? " (equal) " : "(different)") << '\n';
}

不过,我是否遗漏了某些可能导致问题的情况?

另外,选择同尺寸偏移量而非更大尺寸类型的原因如下:

  • 希望在大型偏移量数组中节省内存空间
  • 现有代码生态中,针对std::size_t类型的索引,多数实现会使用与其尺寸相同的有符号类型std::ptrdiff_t作为偏移量,本文旨在正式解答这一常见实践的安全性问题。

内容的提问来源于stack exchange,提问作者Damir Tenishev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:24:52