I'm trying to pass a Nim string (auto-converted to cstring, I guess) to a C function.
The whole thing does work but not consistently (at times, it crashes with " malloc: Incorrect checksum for freed object ....: probably modified after being freed.") and I imagine it has something to do with the item having been freed by the GC.
How do I make it work? As far as I've seen, I cannot use GC_ref with a string. So, what am I supposed to do?
Of course you can pass Nim strings to C functions, but you have to ensure that the Nim string lives as long as it is used by the C lib. Most C libs seems to make a copy of the passed string when the lib uses the string still when the function has terminated. If the C function does not make a copy but continues to use that string, then you would have to GC_ref it or to pass a copy that you allocate yourself with low level functions like alloc().
Maybe copy your Nim string to a Nim Cstring and call GC_ref() on the Nim cstring, I would assume that it may work. Modern Nim strings are value objects, so we can not call GC_Ref on them, but for CStrings it may work still. Otherwise search for procs related to alloc() or create() maybe.
Note that it is not a ARC problem, the default GC just delays deallocation, so that such problems can be hidden for long time.
The real problem is reliable releasing such copied string. Who does release it, the C lib or your code?
That is interesting.
From
https://nim-lang.org/docs/manual.html#types-cstring-type
we have
One can use the builtin procs GC_ref and GC_unref to keep the string data alive
So manual is not clear enough.
You may still allocate unmanaged memory with procs like create() or alloc() and copy the string content with copyMem(). I can not give you example code, I never did that.
Or you may try to use a ref string data type:
type
M = ref string
proc main =
var s = new M
s[] = "Hello"
echo s[]
main()
But let us wait for mratsim or Araq.