使用hiredis调用Redis sadd命令报WRONGTYPE错误如何解决
问题原因与解决建议
WRONGTYPE 错误的核心原因是你本地Redis服务中已存在名为names的key,且该key的存储类型不是集合(Set)类型,因此无法执行sadd、smembers这类集合专属操作。
操作步骤
第一步:清理冲突的历史key
连接本地Redis服务,依次执行以下命令:
- 查看
names的实际存储类型:TYPE names
如果返回值不是none(无该key)或set(集合类型),说明是旧数据冲突 - 删除冲突的key:
DEL names
清理完成后先重新运行代码验证,如果仍报错再继续修改代码隐藏问题。
第二步:修复代码逻辑缺陷
你的现有代码即使解决了key冲突也无法正常获取结果,存在两处核心逻辑错误:
set方法内存泄漏+返回值类型错误sadd执行成功后返回的是整数(成功新增的元素个数),不是字符串,且方法执行完未释放_reply对象会造成内存泄漏,修改参考:
// 方法名改为sadd更贴合语义,避免和string类型的set命令混淆 int sadd(string key, string value){ this->_reply = (redisReply*)redisCommand(this->_connect, "sadd %s %s", key.c_str(), value.c_str()); if (this->_reply == nullptr || this->_reply->type == REDIS_REPLY_ERROR) { printf("操作错误:%s\n", this->_reply? this->_reply->str : "空回复"); freeReplyObject(this->_reply); return -1; } int res = this->_reply->integer; freeReplyObject(this->_reply); return res; }
output方法返回值类型错误smembers执行成功后返回的是数组类型,不是字符串,直接取_reply->str无法拿到正确的集合元素,修改参考:
#include <vector> // 头文件记得加vector引入 vector<string> smembers(string key){ vector<string> res; this->_reply = (redisReply*)redisCommand(this->_connect, "smembers %s", key.c_str()); if (this->_reply == nullptr || this->_reply->type == REDIS_REPLY_ERROR) { printf("操作错误:%s\n", this->_reply? this->_reply->str : "空回复"); freeReplyObject(this->_reply); return res; } for (size_t i = 0; i < this->_reply->elements; i++) { res.push_back(this->_reply->element[i]->str); } freeReplyObject(this->_reply); return res; }
第三步:修改main方法适配返回值
int main(){ Redis *r = new Redis(); if(!r->connect("127.0.0.1", 6379)){ printf("connect error!\n"); return 0; } printf("Sadd names Andy 成功添加数量:%d\n", r->sadd("names", "Andy")); printf("Sadd names Andy 成功添加数量:%d\n", r->sadd("names", "Andy")); printf("Sadd names Alice 成功添加数量:%d\n", r->sadd("names", "Alice")); vector<string> members = r->smembers("names"); printf("names members:\n"); for (auto &item : members) { printf("- %s\n", item.c_str()); } delete r; return 0; }
内容的提问来源于stack exchange,提问作者Lily1024
相关产品推荐
相关产品推荐

