www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - toStringz, and memory management, also fromStringz

reply Joel Christensen <joelcnz gmail.com> writes:
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.

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.

Thanks for any help.

- Joelcnz
Sep 09 2011
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Sep 09 2011
parent Joel Christensen <joelcnz gmail.com> writes:
On 10-Sep-11 3:09 PM, Jonathan M Davis wrote:
 Jonathan M Davis

Ok, now I have a better idea with char pointers. And the std.conv.to worked too. Thanks. - Joelcnz
Sep 09 2011