Skip to content

about freeReply and receiving arrays #20

@ndrean

Description

@ndrean

I have difficulties when receiving arrays from okredis even after using https://github.com/kristoff-it/zig-okredis/blob/master/example.zig.

I use the function "HVALS".

  • I tried the allocated DYNAMICREPLY with freeReply but it panics.
const dynReply = self.redis_client.sendAlloc(DynamicReply, self.allocator, .{ "HVALS", cart_key }) catch |err| switch (err) {
            error.Nil => return 0,
            else => return err,
        };
defer okredis.freeReply(dynReply, self.allocator);
thread 44527306 panic: Invalid free
/Users/nevendrean/.zvm/0.15.1/lib/std/heap/debug_allocator.zig:875:49: 0x100718bd7 in free (htmz)
            if (bucket.canary != config.canary) @panic("Invalid free");
                                                ^
/Users/nevendrean/.zvm/0.15.1/lib/std/mem/Allocator.zig:147:25: 0x100707767 in free__anon_22515 (htmz)
    return a.vtable.free(a.ptr, memory, alignment, ret_addr);
                        ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/types/verbatim.zig:34:31: 0x100788fab in destroy__anon_53691 (htmz)
                allocator.free(self.string);
                              ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:287:43: 0x10076955b in freeReply__anon_49679 (htmz)
                    T.Redis.Parser.destroy(val, rootParser, allocator);
                                          ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/types/reply.zig:52:58: 0x10074f457 in destroy__anon_44731 (htmz)
                    .String => |ver| rootParser.freeReply(ver, allocator),
                                                         ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/types/reply.zig:54:49: 0x10074f583 in destroy__anon_44731 (htmz)
                        for (lst) |elem| destroy(elem, rootParser, allocator);
                                                ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:287:43: 0x10072dcff in freeReply__anon_40730 (htmz)
                    T.Redis.Parser.destroy(val, rootParser, allocator);
                                          ^
/Users/nevendrean/code/zig/htmz/src/kv_cart_manager.zig:224:32: 0x10072d583 in getCartCount (htmz)
        defer okredis.freeReply(dynReply, self.allocator); // This causes "Invalid free" panic
  • If I (miss)use it this way, I don't get a panic but I have okredis memory leaks:
const quantities = self.redis_client.sendAlloc([][]u8, self.allocator, .{ "HVALS", cart_key }) catch |err| switch (err) {
            error.Nil => return 0,
            else => return err,
        };
defer self.allocator.free(quantities);
error(gpa): memory address 0x1030c0000 leaked:                                                                                                                          ✘ INT 23s  system
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser/t_string_blob.zig:70:55: 0x100cba46f in parseAlloc__anon_49617 (htmz)
                const res = try allocator.alignedAlloc(
                                                      ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:208:34: 0x100cba7a3 in ifSupported__anon_49611 (htmz)
                parser.parseAlloc(T, rootParser, allocator.ptr, r)
                                 ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:191:47: 0x100ca2993 in parseImpl__anon_44710 (htmz)
            '$', '=' => return try ifSupported(BlobStringParser, T, allocator, r),
                                              ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:35:29: 0x100ca25b3 in parseAlloc__anon_44704 (htmz)
        return try parseImpl(T, tag, .{ .ptr = allocator }, r);
                            ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser/t_list.zig:61:42: 0x100ca32ff in decodeArray__anon_44699 (htmz)
                    rootParser.parseAlloc(T, allocator.ptr, r)
                                         ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser/t_list.zig:107:32: 0x100ca3873 in parseImpl__anon_44693 (htmz)
                try decodeArray(ptr.child, result, rootParser, allocator, r);
                               ^

error(gpa): memory address 0x1030c0008 leaked: 
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser/t_string_blob.zig:70:55: 0x100cba46f in parseAlloc__anon_49617 (htmz)
                const res = try allocator.alignedAlloc(
                                                      ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:208:34: 0x100cba7a3 in ifSupported__anon_49611 (htmz)
                parser.parseAlloc(T, rootParser, allocator.ptr, r)
                                 ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:191:47: 0x100ca2993 in parseImpl__anon_44710 (htmz)
            '$', '=' => return try ifSupported(BlobStringParser, T, allocator, r),
                                              ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser.zig:35:29: 0x100ca25b3 in parseAlloc__anon_44704 (htmz)
        return try parseImpl(T, tag, .{ .ptr = allocator }, r);
                            ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser/t_list.zig:61:42: 0x100ca32ff in decodeArray__anon_44699 (htmz)
                    rootParser.parseAlloc(T, allocator.ptr, r)
                                         ^
/Users/nevendrean/.cache/zig/p/okredis-0.1.0-Cg726vcEBAAjrhwgBJ2cjL4qN3ircjBsX6iTd7wEFiEC/src/parser/t_list.zig:107:32: 0x100ca3873 in parseImpl__anon_44693 (htmz)
                try decodeArray(ptr.child, result, rootParser, allocator, r);
  • If I use the non allocated send([50]FixBuf(8), .{ "HVALS", cart_key}) calls, and if I don't specify the exact [length]FixBuf(8) that should match the length of the returned array from the HVALS command, I get LengthMismatch.

But I don't know this length in advance.

So one solution is to measure the length with an HLEN and have to hardcode some possibilities

inline for (0..Max) |count| {
            if (item_count == count) {
                const quantities = self.redis_client.send([count]FixBuf(8), .{ "HVALS", cart_key }) 
                ...

But this makes 2 calls to the server.

.array => |arr| {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions