toStringz, and memory management, also fromStringz

Jonathan M Davis jmdavisProg at gmx.com
Fri Sep 9 20:09:46 PDT 2011


On Saturday, September 10, 2011 13:00:02 Joel Christensen wrote:
> Hi,
> 
> In the std.string document at toStringz it has this note:
> 
> 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.
> 
> What does it mean, and what is an example of how to do it?
> 
> It's not done like this is it?
> 
> char* a = cast(char*)toStringz( "test" );
> char* b = cast(char*)toStringz( "word" );
> hold ~= a;
> hold ~= b;
> 
> char* cstr2 = al_get_config_value( cfg, a, b );
> 
> My programs using a C library do crash when exiting some times.

It means that you need to keep a pointer to the result of toStringz around if 
the C function that you pass it to keeps a pointer to it. As long as your D 
code still has a copy of the pointer, the GC won't collect it. But if your D 
code doesn't have a copy of the pointer, then the GC may choose to collect it 
at some point. And once it collects it, the C code which kept the pointer has 
a pointer to freed memory and will have memory corruption problems (which 
could result in crash among other things). If the C code doesn't keep a 
pointer to the data that you pass to it, then it's not an issue. It's just a 
problem if the C code retains a pointer to it.

> Also, how do I go the other way round, some thing like toDString. I've
> made my own version. I can't seem to find fromStringz.

If you want to convert from a pointer to a string, use std.conv.to. It should 
do it. If it doesn't, it's a bug.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list