我有一个函数bar(S* x, uint y)
,一个结构S
定义如下:
typedef struct S {
T** arr;
uint length;
} S;
其中length
是arr
指针指向的数组的长度,T
是其他结构。在我的代码中初始化结构时,所述数组使用calloc
动态分配。
现在,在bar
内,我有这样的电话:
uint left = y*2+1;
uint right = y*2+2;
uint boundary = x->length-1;
bool left_exists = (left <= boundary && x->arr[left]);
bool right_exists = (right <= boundary && x->arr[right]);
if (left_exists && right_exists) {//do something}
现在,我的理解是,例如,如果right
引用无效索引,则不会有任何内容破坏,因为条件的第一部分只会短路。
但是,我使用x
对我的程序进行了测试,x->length
为2,并且bar
为y
,其中bool right_exists = (right <= boundary && x->arr[right]);
为0。不会出现段错误(正如我所料),但我做从Valgrind那里得到一条关于从这一行开始无效读取8个字节(我的架构上指针的大小)的警告:
x->arr[right]
我不确定导致这种情况的原因 - 如果我确实执行了{{1}},我会理解,但是我的代码不能阻止这种情况吗?