On Thursday, 28 February 2019 at 04:26:47 UTC, Sam Johnson wrote:
Update: it seems that all I need to do is GC.addRoot(output);
and memory leak goes away. I think I have answered my own
question.
If you know what you are doing. Otherwise you just postpone
troubles due to mixed allocator/deallocator which will result in
memory corruption or just crash. I mean you definitely need to
remove that root and free() when you're done with it at some
point later.
Also fromStringz() may internally do implicit GC copy, inspect
its source, if it just appends to an array or something similar,
this will likely to implicitly allocate using GC.
If you just want to copy string then arrays has a useful
.dup()/.idup() methods(properties?)[1] that should give you a GC
managed copy of original, if I'm not missing something...
If I understood problem correctly then the safest in this case
will add scope(exit)[1] to free() array.
char *output = cast(char *) malloc(output_length);
scope(exit) free(output); // will go away when leave scope,
both normal/exception ways
another option will be making RAII struct wrapper that free() on
destruction, possibly also using RefCounted[2]
To know where GC allocations are made there is -vgc flag for DMD,
it was added to help writting GC-less code if that's absolutely
needed, but you can use it to know if you are not messing up
malloc-free with GC alloc/free.
And finally, don't take what I say too seriously, I do D on
ocassion these days so there might be some changes in how things
works or I might just forgot how it really works.
[1] https://dlang.org/spec/arrays.html#array-properties
[2] https://dlang.org/spec/statement.html#scope-guard-statement
[3] https://dlang.org/phobos/std_typecons.html#RefCounted