C语言错误排查:结构体与void*无法进行!=比较的问题
解决
invalid operands to binary !=错误:结构体与NULL类型不匹配的问题 嘿,我来帮你搞定这个错误!你碰到的invalid operands to binary !=错误,核心问题是类型不匹配:你尝试把一个dataframe结构体实例和NULL(空指针)做比较,这在C语言里是完全不允许的操作。
为什么会报错?
咱们拆解下你的代码逻辑:
new->bucket是dataframe*类型的数组,所以new->bucket[i]是一个实实在在的dataframe结构体对象,不是指针类型。NULL是void*类型的空指针,C语言不支持直接用结构体和指针进行相等/不等比较——就像你不能拿一个整数和一个内存地址比大小一样,根本不是同一类数据。
而且更关键的是,你这里的遍历逻辑也错了:你循环的是刚创建的新桶,但新桶已经被你用ncalloc初始化并把所有元素status设为EMPTY了,这完全不是你想要的“判断旧桶里有没有有效数据”的逻辑啊!
怎么修正?
结合你用status标记元素状态的哈希表设计,我们需要做这几个关键调整:
- 用
status字段判断有效性:不要和NULL比较,而是检查旧桶元素的status是否为FULL——这才是你设计里标记“存在有效数据”的正确方式。 - 遍历旧桶而非新桶:我们要把旧哈希表里的有效数据迁移到新桶,所以循环应该遍历
ass->bucket(旧桶),而不是new->bucket。 - 修复迁移逻辑:原来的
new->bucket[i / multi] = ass->bucket[i];逻辑完全不对——桶大小扩容后,旧索引不能直接映射到新桶,得重新计算哈希值、处理冲突,否则会丢失数据。
下面是修正后的完整代码:
enum dfStatus { EMPTY = 2, FULL, REMOVED }; typedef struct dataframe { void *key; void *data; enum dfStatus status; } dataframe; typedef struct assoc { dataframe *bucket; unsigned int buckCnt; unsigned int totalCnt; unsigned int multip; unsigned int keysize; } assoc; // 假设你有一个哈希计算函数,替换成你实际的实现 unsigned int hash_function(void *key, unsigned int keysize, unsigned int bucket_count) { unsigned char *bytes = (unsigned char*)key; unsigned int hash = 0; for (unsigned int i = 0; i < keysize; i++) { hash = hash * 31 + bytes[i]; } return hash % bucket_count; } assoc* _assoc_resize(assoc* a) { assoc *ass = a, *new; unsigned int old_size = ass->buckCnt; unsigned int multi = ass->multip * 2; unsigned int new_size = old_size * 2; // 初始化新桶,所有元素标记为EMPTY dataframe *new_bucket = ncalloc(new_size, sizeof(dataframe)); for (unsigned int i = 0; i < new_size; i++) { new_bucket[i].status = EMPTY; } // 初始化新的assoc结构体 new = ncalloc(1, sizeof(assoc)); new->multip = multi; new->bucket = new_bucket; new->buckCnt = new_size; new->totalCnt = 0; new->keysize = ass->keysize; // 遍历旧桶,迁移所有有效数据 for (unsigned int i = 0; i < old_size; i++) { dataframe *old_df = &ass->bucket[i]; // 正确判断:检查元素是否为有效状态 if (old_df->status == FULL) { // 重新计算哈希值,找到新桶中的位置 unsigned int idx = hash_function(old_df->key, ass->keysize, new_size); // 处理哈希冲突:线性探测找下一个可用位置 while (new_bucket[idx].status == FULL) { idx = (idx + 1) % new_size; } // 复制有效元素到新桶 new_bucket[idx] = *old_df; new->totalCnt++; } } // 释放旧哈希表的资源 free(ass->bucket); free(ass); return new; }
额外提醒
- 你原来代码里的
SCALEFACTOR没有定义,记得补充这个常量的具体值哦。 - 哈希冲突的处理逻辑(比如线性探测、二次探测)可以根据你的需求调整,上面的示例用了最基础的线性探测。
- 确保
ncalloc是正确封装的calloc函数,能把内存初始化为0,避免出现不确定的状态。
内容的提问来源于stack exchange,提问作者Davospike
相关产品推荐
相关产品推荐

