Thread overview
toStringz note about keeping references
Oct 14, 2012
Andrej Mitrovic
Oct 15, 2012
Kagamin
Oct 15, 2012
Kagamin
October 14, 2012
Docs of toStringz:

[begin]
pure nothrow immutable(char)* toStringz(string s);
Returns a C-style zero-terminated string equivalent to s. s must not
contain embedded '\0''s as any C function will treat the first '\0'
that it sees as the end of the string. If s.empty is true, then a
string containing only '\0' is returned.

Important Note: When passing a char* to a C function, and the C
function keeps it around for any reason, make sure that you keep a
reference to it in your D code. Otherwise, it may go away during a
garbage collection cycle and cause a nasty bug when the C code tries
to use it.
[end]

Why is this note put here? It makes sense for char*, but I don't think it makes sense to put this in the toStringz docs because this function operates on immutable data and returns immutable data, so this rule doesn't apply to it.

toStringz takes a string (immutable(char)[]), and the GC will not
reclaim immutable data until app exit.

For example:

import std.stdio;
import std.string;
import core.memory;

void test()
{
    string x = "foo".idup;
    const(char)* str = toStringz(x);
    writefln("\n-- Address: %s-- \n", str);
}

void main()
{
    test();
    GC.collect();
    writeln("\n --Collect Done-- \n");
}

If you build druntime with -debug=PRINTF and run the above (you will need git HEAD to compile druntime like that):

-- Address: 972FA0--

GC.fullCollect()
processing GC Marks, 8c1824
cache entry 0 has base ptr 0	size 0	flags 0
cache entry 1 has base ptr 0	size 0	flags 0
cache entry 2 has base ptr 0	size 0	flags 0
cache entry 3 has base ptr 0	size 0	flags 0
cache entry 4 has base ptr 0	size 0	flags 0
cache entry 5 has base ptr 0	size 0	flags 0
cache entry 6 has base ptr 0	size 0	flags 0
cache entry 7 has base ptr 0	size 0	flags 0
	collecting 00971FE0
	collecting 00972FB0
	collecting 00972FC0
	collecting 00972FD0
	collecting 00972FE0
	collecting 00972FF0

 --Collect Done--

processing GC Marks, 0
	collecting 00972FA0

"00972FA0" was only reclaimed upon app exit, so there's no fear that a GC cycle will destroy immutable data which might be pointed to in a C function.

So shouldn't that char* note be put somewhere else? E.g. in the interfacing with C section maybe.
October 15, 2012
Probably a bug in GC, immutable data should be collected if not needed.
October 15, 2012
It's also possible that if a function reserves stack without clearing it, some old values may remain in the stack which were passed to other functions, so you'll have false pointers.