Here is the toy module I was trying, intent of the module(joinedGet) was to get the hmset return value into a String separated by #.
But I am getting heap errors and in turn sig segv. I am using RC03 redis build with provided jemalloc allocator.
Requesting to suggest if any issues with my Allocation and free strategy below.
/* helper routine to joinResponses
*/
//responseLens is currently unused.
char* joinResponses(char *responses[], size_t* responseLens, size_t n, size_t totalLen, size_t* joinStrLen)
{
char* str;
*joinStrLen = totalLen + n - 1;
str = (char*) RedisModule_Alloc(*joinStrLen);
str[0] = '\0';
// Append n - 1 responses with a separator #
size_t i;
for( i = 0 ; i < n - 1 ; i++) {
strcat(str, responses[i]);
//optimize since we know the response length.
length = strlen(str);
str[length] = '#';
str[length+1] = '\0';
}
// Append the last String
strcat(str, responses[i]);
return str;
}
/* implementation of joinedGet Command
*/
int joinedGet_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
//Enable Auto memory
RedisModule_AutoMemory(ctx);
if (argc != 2)
return RedisModule_WrongArity(ctx);
RedisModuleCallReply *reply = RedisModule_Call(ctx,"HGETALL", "s", argv[1]);
if (RedisModule_CallReplyType(reply) == REDISMODULE_REPLY_ARRAY) {
size_t replyLen = RedisModule_CallReplyLength(reply);
if( replyLen > 1) {
size_t idx;
size_t totalLen = 0;
char **response = (char**) RedisModule_Alloc( sizeof(char*) * replyLen);
size_t *responseLens = (size_t *) RedisModule_Alloc(sizeof(size_t) * replyLen);
for(idx = 0; idx < replyLen; idx++) {
RedisModuleCallReply* subreply = RedisModule_CallReplyArrayElement(reply,idx);
RedisModuleString *mystr = RedisModule_CreateStringFromCallReply(subreply);
size_t len;
char *ptr = RedisModule_StringPtrLen(mystr,&len);
totalLen += len;
responseLens[idx] = len;
response[idx] = ptr;
}
size_t joinStrLen;
char *joinStr = joinResponses(response, responseLens, replyLen, totalLen, &joinStrLen);
//ok to still free despite AutoMemory
RedisModule_Free(response);
RedisModule_Free(responseLens);
RedisModule_ReplyWithArray(ctx,2);
RedisModule_ReplyWithLongLong(ctx, joinStrLen);
RedisModule_ReplyWithStringBuffer(ctx, joinStr, joinStrLen);
} else {
RedisModule_ReplyWithCallReply(ctx,reply);
}
}
return REDISMODULE_OK;
}