digitalmars.D.learn - Something wrong with GC
- stunaep (5/51) Mar 20 2016 The gc throws invalid memory errors if I use Arrays from
- rikki cattermole (6/66) Mar 20 2016 That looks like an error indeed.
- thedeemon (14/16) Mar 21 2016 Those arrays are for RAII-style deterministic memory release,
- stunaep (9/43) Mar 22 2016 So what am I do to? Any other language can do such a thing so
- Edwin van Leeuwen (22/35) Mar 22 2016 Is there a particular reason why you don't want to use the
- thedeemon (8/9) Mar 23 2016 Just learn more about available containers and their semantics.
- tsbockman (3/7) Mar 21 2016 I don't know what your larger goal is, but maybe
- ag0aep6g (7/25) Mar 22 2016 I can reproduce the InvalidMemoryOperationError with git head dmd, but
- ag0aep6g (6/7) Mar 23 2016 And it's been fixed:
The gc throws invalid memory errors if I use Arrays from std.container. For example, this throws an InvalidMemoryOperationError:import std.stdio; import std.container; void main() { new Test(); } class Test { private Array!string test = Array!string(); this() { test.insert("test"); writeln(test[0]); } }and here's the stack tracetestt.exe!app.onInvalidMemoryOperationError( void* _param_0 ) Line 21 D testt.exe!_D2gc2gc2GC134__T9runLockedS57_D2gc2gc2GC11removeRangeMFNbNiPvZ2goFNbNiPS2gc2gc3GcxPvZvS19_D2gc2gc9otherTimelS19_D2gc2gc9numOtherslTPS2gc2gc3GcxTPvZ9runLockedMFNbNi PS2gc2gc3GcxKPvZv() + 0x52 bytes D testt.exe!_D2gc2gc2GC11removeRangeMFNbNiPvZv() + 0x29 bytes D testt.exe!gc_removeRange() + 0x21 bytes D testt.exe!_D4core6memory2GC11removeRangeFNbNixPvZv() + 0xd bytes D testt.exe!std.container.array.Array!string.Array.Payload.~this() Line 229 + 0x1f bytes D testt.exe!object._destructRecurse!(std.container.array.Array!string.Array.Payloa )._destructRecurse( std.container.array.Array!string.Array.Payload* s ) Line 2409 + 0xd bytes D testt.exe!object.destroy!(std.container.array.Array!string.Arr y.Payload).destroy( std.container.array.Array!string.Array.Payload* obj ) Line 2778 + 0xd bytes D testt.exe!std.typecons.RefCounted!(std.container.array.Array!s ring.Array.Payload, cast(RefCountedAutoInitialize)0).RefCounted.~this() Line 4864 + 0x10 bytes D testt.exe!std.container.array.Array!string.Array.~this() Line 198 + 0x15 bytes D testt.exe!app.Test.~this() Line 10 + 0x19 bytes D testt.exe!rt_finalize2() + 0xb8 bytes D testt.exe!rt_finalizeFromGC() + 0x24 bytes D testt.exe!_D2gc2gc3Gcx5sweepMFNbZm() + 0x3a3 bytes D testt.exe!_D2gc2gc3Gcx11fullcollectMFNbbZm() + 0x57a bytes D testt.exe!_D2gc2gc2GC86__T9runLockedS56_D2gc2gc2GC18fullCollectNoStackMFNbZ2goFNbPS2gc2gc3GcxZmTPS2gc2gc3GcxZ9runLockedM NbKPS2gc2gc3GcxZm() + 0x72 bytes D testt.exe!_D2gc2gc2GC18fullCollectNoStackMFNbZv() + 0x11 bytes D testt.exe!gc_term() + 0x14 bytes D testt.exe!rt_term() + 0x9e bytes D testt.exe!_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv() + 0x4d bytes D testt.exe!_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv() + 0x6f bytes D testt.exe!_d_run_main() + 0x419 bytes D testt.exe!__entrypoint.main( int argc, char** argv ) + 0x22 bytes D testt.exe!__tmainCRTStartup() Line 255 + 0x12 bytes D kernel32.dll!0000000076cd59cd ntdll.dll!0000000076f0b891Not sure what to do here
Mar 20 2016
On 20/03/16 8:49 PM, stunaep wrote:The gc throws invalid memory errors if I use Arrays from std.container. For example, this throws an InvalidMemoryOperationError:That looks like an error indeed. But move the initialization of Array into the constructor. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirusimport std.stdio; import std.container; void main() { new Test(); } class Test { private Array!string test = Array!string(); this() { test.insert("test"); writeln(test[0]); } }and here's the stack tracetestt.exe!app.onInvalidMemoryOperationError( void* _param_0 ) Line 21 D testt.exe!_D2gc2gc2GC134__T9runLockedS57_D2gc2gc2GC11removeRangeMFNbNiPvZ2goFNbNiPS2gc2gc3GcxPvZvS19_D2gc2gc9otherTimelS19_D2gc2gc9numOtherslTPS2gc2gc3GcxTPvZ9runLockedMFNbNiKPS2gc2gc3GcxKPvZv() + 0x52 bytes D testt.exe!_D2gc2gc2GC11removeRangeMFNbNiPvZv() + 0x29 bytes D testt.exe!gc_removeRange() + 0x21 bytes D testt.exe!_D4core6memory2GC11removeRangeFNbNixPvZv() + 0xd bytes D testt.exe!std.container.array.Array!string.Array.Payload.~this() Line 229 + 0x1f bytes D testt.exe!object._destructRecurse!(std.container.array.Array!string.Array.Payload)._destructRecurse( std.container.array.Array!string.Array.Payload* s ) Line 2409 + 0xd bytes D testt.exe!object.destroy!(std.container.array.Array!string.Array.Payload).destroy( std.container.array.Array!string.Array.Payload* obj ) Line 2778 + 0xd bytes D testt.exe!std.typecons.RefCounted!(std.container.array.Array!string.Array.Payload, cast(RefCountedAutoInitialize)0).RefCounted.~this() Line 4864 + 0x10 bytes D testt.exe!std.container.array.Array!string.Array.~this() Line 198 + 0x15 bytes D testt.exe!app.Test.~this() Line 10 + 0x19 bytes D testt.exe!rt_finalize2() + 0xb8 bytes D testt.exe!rt_finalizeFromGC() + 0x24 bytes D testt.exe!_D2gc2gc3Gcx5sweepMFNbZm() + 0x3a3 bytes D testt.exe!_D2gc2gc3Gcx11fullcollectMFNbbZm() + 0x57a bytes D testt.exe!_D2gc2gc2GC86__T9runLockedS56_D2gc2gc2GC18fullCollectNoStackMFNbZ2goFNbPS2gc2gc3GcxZmTPS2gc2gc3GcxZ9runLockedMFNbKPS2gc2gc3GcxZm() + 0x72 bytes D testt.exe!_D2gc2gc2GC18fullCollectNoStackMFNbZv() + 0x11 bytes D testt.exe!gc_term() + 0x14 bytes D testt.exe!rt_term() + 0x9e bytes D testt.exe!_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv() + 0x4d bytes D testt.exe!_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv() + 0x6f bytes D testt.exe!_d_run_main() + 0x419 bytes D testt.exe!__entrypoint.main( int argc, char** argv ) + 0x22 bytes D testt.exe!__tmainCRTStartup() Line 255 + 0x12 bytes D kernel32.dll!0000000076cd59cd ntdll.dll!0000000076f0b891Not sure what to do here
Mar 20 2016
On Sunday, 20 March 2016 at 07:49:17 UTC, stunaep wrote:The gc throws invalid memory errors if I use Arrays from std.container.Those arrays are for RAII-style deterministic memory release, they shouldn't be freely mixed with GC-allocated things. What happens here is while initializing Array sees it got some GC-ed value type (strings), so it tells GC to look after those strings. When your program ends runtime does a GC cycle, finds your Test object, calls its destructor that calls Array destructor that tries to tell GC not to look at its data anymore. But during a GC cycle it's currently illegal to call such GC methods, so it throws an error. Moral of this story: try not to store "managed" (collected by GC) types in Array and/or try not to have Arrays inside "managed" objects. If Test was a struct instead of a class, it would work fine.
Mar 21 2016
On Monday, 21 March 2016 at 07:55:39 UTC, thedeemon wrote:On Sunday, 20 March 2016 at 07:49:17 UTC, stunaep wrote:So what am I do to? Any other language can do such a thing so trivially... I also run into the same problem with emsi_containers TreeMap. It is imperative that I can store data such asThe gc throws invalid memory errors if I use Arrays from std.container.Those arrays are for RAII-style deterministic memory release, they shouldn't be freely mixed with GC-allocated things. What happens here is while initializing Array sees it got some GC-ed value type (strings), so it tells GC to look after those strings. When your program ends runtime does a GC cycle, finds your Test object, calls its destructor that calls Array destructor that tries to tell GC not to look at its data anymore. But during a GC cycle it's currently illegal to call such GC methods, so it throws an error. Moral of this story: try not to store "managed" (collected by GC) types in Array and/or try not to have Arrays inside "managed" objects. If Test was a struct instead of a class, it would work fine.public class Example1 { private File file; public this(File f) { this.file = f; } }orpublic class Example2 { private int one; private int two; public this(int one, int two) { this.one = one; this.two = two; } }in a tree map and list of some sort. Neither of the above work whether they are classes or structs and it's starting to become quite bothersome...
Mar 22 2016
On Tuesday, 22 March 2016 at 13:46:41 UTC, stunaep wrote:Is there a particular reason why you don't want to use the standard ranges? public class Example2 { private int one; private int two; public this(int one, int two) { this.one = one; this.two = two; } } void main() { auto myExamplesList = [ new Example2( 6,3 ), new Example2(7,5) ]; // Note that if you do a lot of appending then using Appender is more performant than ~= myExamplesList ~= new Example2(9,1); } For trees there is also redBlackTreepublic class Example2 { private int one; private int two; public this(int one, int two) { this.one = one; this.two = two; } }in a tree map and list of some sort. Neither of the above work whether they are classes or structs and it's starting to become quite bothersome...
Mar 22 2016
On Tuesday, 22 March 2016 at 13:46:41 UTC, stunaep wrote:So what am I do to?Just learn more about available containers and their semantics. Maybe you don't need Array!T when there is a simple T[]. If you think you do need Array, then think about memory management: where are you going to allocate the data - in the GC heap or outside it. Depending on your answers there are different approaches. It's all solvable if you pause and think what exactly you're trying to do.
Mar 23 2016
On Sunday, 20 March 2016 at 07:49:17 UTC, stunaep wrote:The gc throws invalid memory errors if I use Arrays from std.container. ... Not sure what to do hereI don't know what your larger goal is, but maybe std.array.Appender would be a better fit?
Mar 21 2016
On 20.03.2016 08:49, stunaep wrote:The gc throws invalid memory errors if I use Arrays from std.container. For example, this throws an InvalidMemoryOperationError:I can reproduce the InvalidMemoryOperationError with git head dmd, but there doesn't seem to be a problem with 2.070. So I'd say this is a regression in the development version. I've filed an issue: https://issues.dlang.org/show_bug.cgi?id=15821 You're probably building dmd/phobos from git, or you're using a nightly, right? Maybe you can go back to 2.070.2 until this is sorted out.import std.stdio; import std.container; void main() { new Test(); } class Test { private Array!string test = Array!string(); this() { test.insert("test"); writeln(test[0]); } }
Mar 22 2016
On 22.03.2016 16:56, ag0aep6g wrote:I've filed an issue: https://issues.dlang.org/show_bug.cgi?id=15821And it's been fixed: https://github.com/D-Programming-Language/druntime/pull/1519 Since the issue was a regression, the fix was made against the stable branch. It's going to be in the next release. But it's not yet in master, which means it's also not going to be in the nightlies for now.
Mar 23 2016