From the D Blog -- Interfacing D with C: Strings Part One

John Colvin john.loughran.colvin at gmail.com
Mon May 24 17:44:26 UTC 2021


On Monday, 24 May 2021 at 16:16:53 UTC, Steven Schveighoffer 
wrote:
> On 5/24/21 10:02 AM, Mike Parker wrote:
>> The latest post in the D and C series dives into the weeds of 
>> D and C strings: how they're implemented, when you need to 
>> NUL-terminate your D strings and when you don't, and how the 
>> storage of literals in memory allows you to avoid NUL 
>> termination in one case you might not have considered and 
>> another case that you shouldn't rely on but can in practice 
>> with the current compilers.
>> 
>> There are at least two more posts worth of information to go 
>> into on this topic, but everything in this post is enough to 
>> cover many use cases of D to C string interop.
>> 
>> The blog:
>> https://dlang.org/blog/2021/05/24/interfacing-d-with-c-strings-part-one/
>> 
>> Reddit:
>> https://www.reddit.com/r/programming/comments/njyf76/interfacing_d_with_c_strings_part_one/
>> 
>
> Nice article!
>
> Note that there is a huge pitfall awaiting you if you use 
> `toStringz`: garbage collection. You may want to amend the 
> article to identify this pitfall.
>
> And I'm not talking about requiring `@nogc`, I'm talking about 
> the GC collecting the data while C is still using it.
>
> In your example:
>
> ```d
> puts(s1.toStringz());
> ```
>
> This leaves a GC-collectible allocation in C land. For `puts`, 
> it's fine, as the data is not used past the call, but in 
> something else that might keep it somewhere not accessible to 
> the GC, you'll want to assign that to a variable that lasts as 
> long as the resource is used.
>
> -Steve

It’s worse than that, no? If the only reference to GC data isn’t 
on the stack of a tracked thread, in GC allocated memory or in a 
tracked root then it can be freed. Even in D:

void foo(int* a) {
     int** b = cast(int**) malloc((int*).sizeof);
     *b = a;
     a = null;
     GC.collect();
     **b = 4; // whoops!!
}

foo(new int);

Right? Obviously that collection could be from calling another 
function (e.g. a callback from C to D code) or from another 
thread. Or am I missing something?


More information about the Digitalmars-d-announce mailing list