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



我有一个函数,可以在我的程序中像这样将元素插入哈希表中:

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 )

出现"分段错误"错误。当我调用插入函数时,程序指针在 while 循环处停止。

我想知道问题出在哪里?

(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1)

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

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

现在在你的情况下

while(hashArray[hashIndex] != NULL && hashArray[hashIndex]->key != -1)

如果hashArray[hashIndex]结果是NULL,则不会评估第二部分。

这意味着您是安全的。

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

因此,最适合您的解决方案是保持原样。

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

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

相关内容

  • 没有找到相关文章

最新更新