www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Leaving a pointer to it on the stack

reply Andre Pany <andre s-e-a-p.de> writes:
Hi,

in the specification 
https://dlang.org/spec/interfaceToC.html#storage_allocation there 
is this paragraph:
"Leaving a pointer to it on the stack (as a parameter or 
automatic variable), as the garbage collector will scan the 
stack."

I have some trouble to understand what does this mean. Given this 
example:

```
import std;

void main()
{
	int* i;
	sample(&i);
	writeln(*i);
}

extern(C) export void sample(int** i)
{
	*i = new int();
	**i = 42;
}
```

Int variable is created on the heap. How do I leave a pointer on 
the stack?
(In the real coding, sample function will be called from Delphi)

Kind regards
André
Aug 13 2020
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 13 August 2020 at 20:04:59 UTC, Andre Pany wrote:
 Hi,

 in the specification 
 https://dlang.org/spec/interfaceToC.html#storage_allocation 
 there is this paragraph:
 "Leaving a pointer to it on the stack (as a parameter or 
 automatic variable), as the garbage collector will scan the 
 stack."

 I have some trouble to understand what does this mean. Given 
 this example:

 ```
 import std;

 void main()
 {
 	int* i;
 	sample(&i);
 	writeln(*i);
 }

 extern(C) export void sample(int** i)
 {
 	*i = new int();
 	**i = 42;
 }
 ```

 Int variable is created on the heap. How do I leave a pointer 
 on the stack?
You just did - the `int* i` is a pointer left on the stack for the duration of `main` so the GC won't collect it until after main returns. But after main returns, even if `sample` kept a copy of it somewhere in some other location, the GC might reap it...
Aug 13 2020
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/13/20 4:04 PM, Andre Pany wrote:
 Hi,
 
 in the specification 
 https://dlang.org/spec/interfaceToC.html#storage_allocation there is 
 this paragraph:
 "Leaving a pointer to it on the stack (as a parameter or automatic 
 variable), as the garbage collector will scan the stack."
 
 I have some trouble to understand what does this mean. Given this example:
 
 ```
 import std;
 
 void main()
 {
      int* i;
      sample(&i);
      writeln(*i);
 }
 
 extern(C) export void sample(int** i)
 {
      *i = new int();
      **i = 42;
 }
 ```
 
 Int variable is created on the heap. How do I leave a pointer on the stack?
 (In the real coding, sample function will be called from Delphi)
 
The garbage collector scans all of the stack as if it were an array of pointers. So if you have a pointer to it anywhere on the stack, it won't be collected. However, it only scans threads that the runtime knows about. -Steve
Aug 13 2020
parent reply Andre Pany <andre s-e-a-p.de> writes:
On Thursday, 13 August 2020 at 20:11:50 UTC, Steven Schveighoffer 
wrote:
 On 8/13/20 4:04 PM, Andre Pany wrote:
 Hi,
 
 in the specification 
 https://dlang.org/spec/interfaceToC.html#storage_allocation 
 there is this paragraph:
 "Leaving a pointer to it on the stack (as a parameter or 
 automatic variable), as the garbage collector will scan the 
 stack."
 
 I have some trouble to understand what does this mean. Given 
 this example:
 
 ```
 import std;
 
 void main()
 {
      int* i;
      sample(&i);
      writeln(*i);
 }
 
 extern(C) export void sample(int** i)
 {
      *i = new int();
      **i = 42;
 }
 ```
 
 Int variable is created on the heap. How do I leave a pointer 
 on the stack?
 (In the real coding, sample function will be called from 
 Delphi)
 
The garbage collector scans all of the stack as if it were an array of pointers. So if you have a pointer to it anywhere on the stack, it won't be collected. However, it only scans threads that the runtime knows about. -Steve
If I understand it right, this paragraph doesn't help in my real scenario where sample (Dll) is called from a delphi executable. It is another runtime (delphi). But on the other side, as D GC only runs if something new should be allocated on D side, I can safely assume that the Delphi caller can access the heap variables? Of course as long as it doesn't store the references and use it later... Kind regards Andre
Aug 13 2020
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/13/20 4:51 PM, Andre Pany wrote:
 On Thursday, 13 August 2020 at 20:11:50 UTC, Steven Schveighoffer wrote:
 The garbage collector scans all of the stack as if it were an array of 
 pointers. So if you have a pointer to it anywhere on the stack, it 
 won't be collected.

 However, it only scans threads that the runtime knows about.
If I understand it right, this paragraph doesn't help in my real scenario where sample (Dll) is called from a delphi executable.
So in your real world scenario, a non-D thread/program is calling sample, and it controls the location of *i? If so, then no, you can't depend on D not collecting that data, because D might not scan that location.
 It is another runtime (delphi). But on the other side, as D GC only runs 
 if something new should be allocated on D side, I can safely assume that 
 the Delphi caller can access the heap variables? Of course as long as it 
 doesn't store the references and use it later...
As long as you aren't allocating again later, yes. You can also disable collections and only run them when you know it's safe to do so. -steve
Aug 13 2020
parent Andre Pany <andre s-e-a-p.de> writes:
On Thursday, 13 August 2020 at 21:10:57 UTC, Steven Schveighoffer 
wrote:
 On 8/13/20 4:51 PM, Andre Pany wrote:
 [...]
So in your real world scenario, a non-D thread/program is calling sample, and it controls the location of *i? If so, then no, you can't depend on D not collecting that data, because D might not scan that location.
 [...]
As long as you aren't allocating again later, yes. You can also disable collections and only run them when you know it's safe to do so. -steve
Thanks for the answers. This clarifies all my questions. Kind regards Andre
Aug 13 2020