Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
March 14, 2015 Garbage collector returning pointers | ||||
---|---|---|---|---|
| ||||
Hi, I have a question about how the GC handles this case:
export extern(C) char* foo(){
char[] x = "This is a dynamic D string.".dup;
return(cast(char*)x);
}
Since x is "pointer to array data & length" if it goes out of scope, it's destroyed and the last reference to the array data is gone. Hence, the GC could kick in and free the array data. Is this correct?
Or will the GC know, that there was a pointer to the array data returned and hence a new reference exists as long until someone tells the GC that the pointer is no longer used?
My situation is, that the returned pointer is used to copy the result to some interpreter internal state. Depending on the answers above, there could be a short time where the memory state is "collectable" before the coyping was finished.
--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster
|
March 14, 2015 Re: Garbage collector returning pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Saturday, 14 March 2015 at 18:26:34 UTC, Robert M. Münch wrote: > Hi, I have a question about how the GC handles this case: > > export extern(C) char* foo(){ > char[] x = "This is a dynamic D string.".dup; > > return(cast(char*)x); > } Returning `x.ptr` would look a little nicer. > > Since x is "pointer to array data & length" if it goes out of scope, it's destroyed and the last reference to the array data is gone. Hence, the GC could kick in and free the array data. Is this correct? No. > Or will the GC know, that there was a pointer to the array data returned and hence a new reference exists as long until someone tells the GC that the pointer is no longer used? Yes. The returned pointer is a reference. Once that reference is gone, the GC can collect the array. You don't need to explicitly inform the GC when you're done with the pointer. > My situation is, that the returned pointer is used to copy the result to some interpreter internal state. Depending on the answers above, there could be a short time where the memory state is "collectable" before the coyping was finished. I think you're safe. |
March 14, 2015 Re: Garbage collector returning pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Saturday, 14 March 2015 at 18:26:34 UTC, Robert M. Münch wrote:
> Hi, I have a question about how the GC handles this case:
>
> export extern(C) char* foo(){
> char[] x = "This is a dynamic D string.".dup;
>
> return(cast(char*)x);
> }
>
> Since x is "pointer to array data & length" if it goes out of scope, it's destroyed and the last reference to the array data is gone. Hence, the GC could kick in and free the array data. Is this correct?
>
> Or will the GC know, that there was a pointer to the array data returned and hence a new reference exists as long until someone tells the GC that the pointer is no longer used?
>
> My situation is, that the returned pointer is used to copy the result to some interpreter internal state. Depending on the answers above, there could be a short time where the memory state is "collectable" before the coyping was finished.
As long as the pointer remains on the stack or in a register, the GC will keep the allocation alive. But if your C code stores the pointer on the C heap or in a global, the GC won't know anything about it and can free it.
|
March 15, 2015 Re: Garbage collector returning pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On 2015-03-14 20:45:21 +0000, Marc Schütz said: > As long as the pointer remains on the stack or in a register, the GC will keep the allocation alive. Hi Marc, ok, got it. Thanks. > But if your C code stores the pointer on the C heap or in a global, the GC won't know anything about it and can free it. Ok. I need to dig into how the interpreter handles the returned pointer and how the stack is handled. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
March 15, 2015 Re: Garbage collector returning pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Sunday, 15 March 2015 at 15:08:43 UTC, Robert M. Münch wrote:
> On 2015-03-14 20:45:21 +0000, Marc Schütz said:
>
>> As long as the pointer remains on the stack or in a register, the GC will keep the allocation alive.
>
> Hi Marc, ok, got it. Thanks.
>
>> But if your C code stores the pointer on the C heap or in a global, the GC won't know anything about it and can free it.
>
> Ok. I need to dig into how the interpreter handles the returned pointer and how the stack is handled.
C usually uses manual memory management, therefore I would expect that the interpreter actually documents whom the pointer belongs to, and who is responsible for cleaning it up.
If the interpreter takes ownership, you should just allocate the data with malloc(), and the interpreter will then call free() on it when it doesn't need it any longer. Not sure whether .dup is compatible with that, maybe you'd need to write a small helper that copies things to the C heap.
Otherwise, maybe the interpreter will call you back when it wants to free the memory.
In both cases, you don't need to use GC pointers at all, because it's actually doing manual memory management.
|
March 16, 2015 Re: Garbage collector returning pointers | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | On 2015-03-15 15:57:43 +0000, Marc Schütz said: >> Ok. I need to dig into how the interpreter handles the returned pointer and how the stack is handled. > > C usually uses manual memory management, therefore I would expect that the interpreter actually documents whom the pointer belongs to, and who is responsible for cleaning it up. What I'm trying to understand is how the returned pointer is used and when the GC can kick in. I tracked the return code from the DLL. The returned pointer is returned in EAX register (conforming to the C calling convention). Then the interpreter uses this pointer for some time (in my case to create a copy). It than continues, and at some point the EAX register gets some other value. This is the point, wher no reference to the D GC allocated memory can anylonger be found. Hence the GC should be free to free the memory. > If the interpreter takes ownership, you should just allocate the data with malloc(), and the interpreter will then call free() on it when it doesn't need it any longer. Not sure whether .dup is compatible with that, maybe you'd need to write a small helper that copies things to the C heap. Yes, exactly. And the problem is, that it's not clear to me (yet) when the interpreter takes ownership and when not. Am I right, that I can query() the D GC to check if a pointer is known / can be found or not? It would be cool if I could query D from the interpreter and ask: "Will this pointer be freed in the next collector run?" and get back: Yes, or "already has been". -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
Copyright © 1999-2021 by the D Language Foundation