改变while循环中条件的位置会导致C中的分段错误吗?

改变while循环中条件的位置会导致C中的分段错误吗?,c,gcc,data-structures,segmentation-fault,C,Gcc,Data Structures,Segmentation Fault,在我的程序中,我有一个将元素插入哈希表的函数,如下所示: void insert(int key,int data) { struct DataItem *newdata = (struct DataItem*) malloc(sizeof(struct DataItem)); int hashIndex; newdata->key = key; newdata->data = data; hashIndex = hashCode(key

在我的程序中,我有一个将元素插入哈希表的函数,如下所示:

void insert(int key,int data)
{
    struct DataItem *newdata = (struct DataItem*) malloc(sizeof(struct DataItem));
    int  hashIndex;

    newdata->key = key;
    newdata->data = data;

    hashIndex = hashCode(key);

    while(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1)
    {
        ++hashIndex;
        hashIndex %= MAX_SIZE;
    }   

    hashArray[hashIndex] = newdata;
}
这项工作没有任何问题。但是,当我将while循环中条件的位置更改为:

while(hashArray[hashIndex]->key != -1 && hashArray[hashIndex] != NULL )
有一个“分段错误”错误。当我调用insert函数时,程序指针停在while循环

我想知道是什么问题

(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1)
这是因为在这里,如果第一个条件为false,则第二个条件不会执行-这是
&&
运算符的行为-因此,如果
hashArray[hashIndex]
为NULL,它不会通过访问
hashArray[hashIndex]->key来访问无效内存


这是因为在这里,如果第一个条件为false,则不会执行第二个条件-这是
&&
运算符的行为-因此如果
hashArray[hashIndex]
为NULL,它不会通过访问
hashArray[hashIndex]来访问无效内存->键

C
对布尔值
和&进行短路评估。这意味着,如果第一个表达式的计算结果为false,则第二个表达式将不会被计算,并且将直接返回false

现在就你而言

while(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1)
如果
hashArray[hashIndex]
结果为
NULL
,则不会对第二部分进行计算

这意味着你是安全的

但是当您切换顺序并且
hashArray[hashIndex]
确实是
NULL
时会发生什么呢?您在检查前取消引用
NULL
,因此会出现Seg故障


因此,最好的解决方案是保持原样。

C
对布尔值
&&
进行短路评估。这意味着,如果第一个表达式的计算结果为false,则第二个表达式将不会被计算,并且将直接返回false

现在就你而言

while(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1)
如果
hashArray[hashIndex]
结果为
NULL
,则不会对第二部分进行计算

这意味着你是安全的

但是当您切换顺序并且
hashArray[hashIndex]
确实是
NULL
时会发生什么呢?您在检查前取消引用
NULL
,因此会出现Seg故障


因此,对您来说,最好的解决方案是保持原样。

问题是,在第一种情况下,您首先检查
hashArray[hashIndex]!=空值
并且仅当对象存在时才访问
成员。第二个版本将尝试在确保对象已创建之前访问
成员


换句话说,在第二个版本中,
hashArray[hashIndex]
可能是
NULL
,因此条件的第一部分(
hashArray[hashIndex]->key
)等价于
NULL->key
,这导致访问冲突

问题是,在第一种情况下,您首先检查
hashArray[hashIndex]!=空值
并且仅当对象存在时才访问
成员。第二个版本将尝试在确保对象已创建之前访问
成员

换句话说,在第二个版本中,
hashArray[hashIndex]
可能是
NULL
,因此条件的第一部分(
hashArray[hashIndex]->key
)等价于
NULL->key
,这导致访问冲突