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