www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Garbage collector returning pointers

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
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
Mar 14 2015
next sibling parent "anonymous" <anonymous example.com> writes:
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.
Mar 14 2015
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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.
Mar 14 2015
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
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.
Mar 15 2015
parent =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes: