用C语言HashSet解LeetCode217时unsigned int索引引发运行时错误原因
为什么用unsigned int存储哈希索引会触发运行时错误?
我用C语言实现HashSet来解决LeetCode 217. 存在重复元素问题时,为了让计算出的哈希索引始终为正,选择用unsigned int存储索引,结果触发了运行时错误。
错误代码片段:
unsigned int index = key % BUCKET_SIZE; // 问题所在
错误信息:
Line 23: Char 15: runtime error: load of address 0x6258000078f0 with insufficient space for an object of type 'struct ListNode *' [solution.c]
0x6258000078f0: note: pointer points here
我用两种方法修复了问题:
- 使用int存储索引:
int index = key % BUCKET_SIZE; - 对int索引取正:
int index = key % BUCKET_SIZE; if( index < 0) { index *= -1; }
问题原因
核心在于C语言的负数取模规则和无符号整数转换特性:
- 当
key是负数时,key % BUCKET_SIZE的结果符号和key一致,也就是负数(比如-5 % 10的结果是-5)。 - 将这个负数赋值给
unsigned int变量时,C会执行无符号转换:负数会被转换为UINT_MAX + 1 + 负数的超大无符号值(32位系统下UINT_MAX为4294967295)。这个值远超出哈希桶数组的有效下标范围,直接导致数组越界访问非法内存,触发运行时错误。
用int存储索引时,负数下标本身属于C语言的未定义行为,但LeetCode测试环境中可能未触发严重崩溃;而第二种方法通过将负索引转为正数,才是正确处理负数哈希索引的方式,彻底避免了下标越界问题。
内容的提问来源于stack exchange,提问作者Maam maam
相关产品推荐
相关产品推荐

