redis中的intsetUpgradeAndAdd为什么不会越界?

新手上路,请多包涵

static intset intsetUpgradeAndAdd(intset is, int64_t value) {

int prepend = value < 0 ? 1 : 0;
is = intsetResize(is,intrev32ifbe(is->length)+1);
while(length--)             
    _intsetSet(is,length+prepend,_intsetGetEncoded(is,length,curenc));
if (prepend)
    _intsetSet(is,0,value);
else
    _intsetSet(is,intrev32ifbe(is->length),value);

重新申请的数组大小为length+1的数组元素,假如prepend为1,_intsetSet函数访问了下标为length+1的数组元素,最多应该只能访问下标为length的元素吧?

阅读 1.5k
1 个回答
新手上路,请多包涵

因为你没贴出的代码上面有一个 resetsize的操作,已经+1了,所以不会越界。
关键点:

is = intsetResize(is, intrev32ifbe(is->length) + 1);

所有代码:

static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
    // 旧的编码格式
    uint8_t curenc = intrev32ifbe(is->encoding);
    // 插入元素的编码格式
    uint8_t newenc = _intsetValueEncoding(value);
    int length = intrev32ifbe(is->length);
    // 该值是用来判断 value 在 beginning 还是 end 位置插入的标志
    int prepend = value < 0 ? 1 : 0;

    /* First set new encoding and resize */
    is->encoding = intrev32ifbe(newenc);
    // 扩容一个元素
    is = intsetResize(is, intrev32ifbe(is->length) + 1);

    while (length--)
        _intsetSet(is, length + prepend, _intsetGetEncoded(is, length, curenc));

    /* Set the value at the beginning or the end. */
    if (prepend)
        _intsetSet(is, 0, value);
    else
        _intsetSet(is, intrev32ifbe(is->length), value);
    is->length = intrev32ifbe(intrev32ifbe(is->length) + 1);
    return is;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进