digitalmars.D.learn - When this will be freed?
- Andrea Fontana (6/6) Apr 02 2014 auto example(char* test) { return toStringz(to!string(test) ~ "
- Jacob Carlborg (7/11) Apr 02 2014 When there is no reference left to the string, the garbage collector is
- Andrea Fontana (5/18) Apr 02 2014 I mean: if it is an exported function (of a shared library) what
- Benjamin Thaut (8/29) Apr 02 2014 If you pass that string to a C function, there is a reference on the
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (15/27) Apr 04 2014 This is unfortunately only true on x86 32-bit. For x86_64, the
- Steven Schveighoffer (24/46) Apr 04 2014 it
- Jacob Carlborg (13/16) Apr 05 2014 I'm not so familiar with calling conventions and how the stack and
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (17/34) Apr 05 2014 Yes, but it doesn't necessarily contain `s` anymore. Today's
- Jacob Carlborg (7/21) Apr 05 2014 Of course, if the C function is storing the parameter in a global
- John Colvin (5/11) Apr 02 2014 to!string allocates on the GC heap when given a char* (it has to,
auto example(char* test) { return toStringz(to!string(test) ~ " world!"); } When that return string will be freed? What about: extern(C) auto example(....) ?
Apr 02 2014
On 2014-04-02 17:45, Andrea Fontana wrote:auto example(char* test) { return toStringz(to!string(test) ~ " world!"); } When that return string will be freed?When there is no reference left to the string, the garbage collector is free to collect it when it chooses to.What about: extern(C) auto example(....)Same as above, extern(C) does not change how memory is collected. If it is a C function, then it depends entirely on that particular function. -- /Jacob Carlborg
Apr 02 2014
On Wednesday, 2 April 2014 at 15:53:52 UTC, Jacob Carlborg wrote:On 2014-04-02 17:45, Andrea Fontana wrote:That's expected.auto example(char* test) { return toStringz(to!string(test) ~ " world!"); } When that return string will be freed?When there is no reference left to the string, the garbage collector is free to collect it when it chooses to.I mean: if it is an exported function (of a shared library) what happens? There's no reference kept anywhere (in D). So if I'm right it could be freed immediatly by GC. Right?What about: extern(C) auto example(....)Same as above, extern(C) does not change how memory is collected. If it is a C function, then it depends entirely on that particular function.
Apr 02 2014
Am 02.04.2014 17:57, schrieb Andrea Fontana:On Wednesday, 2 April 2014 at 15:53:52 UTC, Jacob Carlborg wrote:If you pass that string to a C function, there is a reference on the stack. So this string will not be freed until that C-function returns. If that C-Function returns, it is very likely however that this was the only reference and the string will be freed the next time the garbage collector runs. Kind Regards Benjamin ThautOn 2014-04-02 17:45, Andrea Fontana wrote:That's expected.auto example(char* test) { return toStringz(to!string(test) ~ " world!"); } When that return string will be freed?When there is no reference left to the string, the garbage collector is free to collect it when it chooses to.I mean: if it is an exported function (of a shared library) what happens? There's no reference kept anywhere (in D). So if I'm right it could be freed immediatly by GC. Right?What about: extern(C) auto example(....)Same as above, extern(C) does not change how memory is collected. If it is a C function, then it depends entirely on that particular function.
Apr 02 2014
On Wednesday, 2 April 2014 at 16:51:57 UTC, Benjamin Thaut wrote:Am 02.04.2014 17:57, schrieb Andrea Fontana:This is unfortunately only true on x86 32-bit. For x86_64, the calling conventions (MS, SysV [1]) say that the first few parameters are passed in registers, and the same is probably true for other architectures. Usually this is still safe, as the pointer will normally either stay in its register, or will be spilled to the stack and kept there as long as the function still needs to use it. But one might imagine a corner case where it temporarily stores the pointer in a global or static variable. Even if the pointer will not be kept by the C function longer than the call, in such cases you would need to keep an additional reference where the GC can see it. [1] https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventionsI mean: if it is an exported function (of a shared library) what happens? There's no reference kept anywhere (in D). So if I'm right it could be freed immediatly by GC. Right?If you pass that string to a C function, there is a reference on the stack. So this string will not be freed until that C-function returns. If that C-Function returns, it is very likely however that this was the only reference and the string will be freed the next time the garbage collector runs.
Apr 04 2014
On Fri, 04 Apr 2014 09:25:49 -0400, Marc Sch=C3=BCtz <schuetzm gmx.net> = wrote:On Wednesday, 2 April 2014 at 16:51:57 UTC, Benjamin Thaut wrote:itAm 02.04.2014 17:57, schrieb Andrea Fontana:I mean: if it is an exported function (of a shared library) what happens? There's no reference kept anywhere (in D). So if I'm right ==could be freed immediatly by GC. Right?If you pass that string to a C function, there is a reference on the =. =stack. So this string will not be freed until that C-function returns=he =If that C-Function returns, it is very likely however that this was t==only reference and the string will be freed the next time the garbage==collector runs.This is unfortunately only true on x86 32-bit. For x86_64, the calling=conventions (MS, SysV [1]) say that the first few parameters are passe=d =in registers, and the same is probably true for other architectures. Usually this is still safe, as the pointer will normally either stay i=n =its register, or will be spilled to the stack and kept there as long a=s =the function still needs to use it. But one might imagine a corner cas=e =where it temporarily stores the pointer in a global or static variable=. =Even if the pointer will not be kept by the C function longer than the==call, in such cases you would need to keep an additional reference whe=re =the GC can see it.In cases where it is stored in global data, and that becomes the only = reference, or if a C heap allocation is made, and the pointer is stored = in = there (perhaps to pass to another C function?), then it's quite possible= = the data could be collected prematurely in another thread. You bring up a good point. This is something that should be considered = when calling extern(C) functions. -Steve
Apr 04 2014
On 2014-04-04 15:25, "Marc Schütz" <schuetzm gmx.net>" wrote:This is unfortunately only true on x86 32-bit. For x86_64, the calling conventions (MS, SysV [1]) say that the first few parameters are passed in registers, and the same is probably true for other architectures.I'm not so familiar with calling conventions and how the stack and registers work. But take this as an example: extern (C) void foo (in char*); void bar () { string s = "asd"; foo(s.ptr); } Even if "s" is passed in a register to "foo", won't the stack of "bar" still be available until "foo" returns? -- /Jacob Carlborg
Apr 05 2014
On Saturday, 5 April 2014 at 11:28:36 UTC, Jacob Carlborg wrote:On 2014-04-04 15:25, "Marc Schütz" <schuetzm gmx.net>" wrote:Yes, but it doesn't necessarily contain `s` anymore. Today's compilers are intelligent enough to see that `s` is never used after the function call, and therefore don't even allocate a stack slot for it. `foo` could be implemented like this (it's a C function, so `in` boils down to `const` without `scope`): char *b; void foo (const char *a) { b = a; // do something complex that causes all the registers to be reused // => the only reference to the string is now in b, outside of the GC's view // --> GC collects here <-- printf(b); // the string may have been collected here }This is unfortunately only true on x86 32-bit. For x86_64, the calling conventions (MS, SysV [1]) say that the first few parameters are passed in registers, and the same is probably true for other architectures.I'm not so familiar with calling conventions and how the stack and registers work. But take this as an example: extern (C) void foo (in char*); void bar () { string s = "asd"; foo(s.ptr); } Even if "s" is passed in a register to "foo", won't the stack of "bar" still be available until "foo" returns?
Apr 05 2014
On 2014-04-05 15:08, "Marc Schütz" <schuetzm gmx.net>" wrote:Yes, but it doesn't necessarily contain `s` anymore. Today's compilers are intelligent enough to see that `s` is never used after the function call, and therefore don't even allocate a stack slot for it.Ok, I see.`foo` could be implemented like this (it's a C function, so `in` boils down to `const` without `scope`): char *b; void foo (const char *a) { b = a; // do something complex that causes all the registers to be reused // => the only reference to the string is now in b, outside of the GC's view // --> GC collects here <-- printf(b); // the string may have been collected here }Of course, if the C function is storing the parameter in a global variable you got problems. You really need to be sure of what the C functions is doing. To be on the safe side there's always GC.addRoot. -- /Jacob Carlborg
Apr 05 2014
On Wednesday, 2 April 2014 at 15:45:06 UTC, Andrea Fontana wrote:auto example(char* test) { return toStringz(to!string(test) ~ " world!"); } When that return string will be freed? What about: extern(C) auto example(....) ?to!string allocates on the GC heap when given a char* (it has to, in order to safely produce immutable data in the string). It will be freed by the first garbage collection ocurring after all references to that memory are dead.
Apr 02 2014