我有一个函数,可以在我的程序中像这样将元素插入哈希表中:
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
,这会导致访问冲突。