On Sun, 25 Jan 2015 08:41:24 +0000, Bayan Rafeh wrote:
>> I tried what you said and I think I see the problem. I managed to
>> create an example program that duplicates the problem:
>>
>>
>> import std.stdio;
>>
>> class A {
>> string path;
>>
>> this(string p) {
>> path = p;
>> }
>> ~this() {
>> }
>> void a(){}
>>
>> void b(){}
>> }
>>
>> class B {
>> A a;
>> this() {
>> this.a = new A("laladiv");
>> }
>> ~this() {
>> delete a;
>> }
>> }
>>
>> void main() {
>> B a = new B(); B b = new B(); delete b;
>> }
>
> The solution was just to remove the "delete a" from the destructor if
> someone comes across this later. Could someone tell me why though?there is no guarantees on destruction order. and GC will not nullify any references to collected data. so, `a` can be already collected and finalized when `B.~this()` is called. yet reference is still there, so `delete a;` will try to delete already dead object. this will lead to crash. without precise GC collector is not able to automatically nullify all "dead" references. and even if there will be such possibility, it can slow down collections alot (GC will nullifying alot of references that aren't used anyway), so i don't think that it do nullifying. there is a simple rule: "dtor should not touch GC-managed resources". this will not give you "predictable destruction order" (that's why most people try to manually delete something in dtor), and this simply will not work at all. if you want predictable destruction order, don't use GC at all, use manual memory management. it doesn't matter which hack you will invent to force destruction order, any hack will either be very fragile, or will not work. this is due to nature of GC-manged memory. so: don't use GC-managed resources in dtors. don't use in any way -- this including accessing 'em. i.e. reading `a.path` in dtor is invalid too. it will not necessarily crash, but it's the source of "use after free" error. and don't even think that you can trick GC using checks from `core.memory`! this will not work too. sure, you can check if memory used by `a` is still alive, but that memory can be used by completely different object! tl;dr: 1. don't use GC-managed objects in dtors. not even try to access 'em. 2. don't try to trick GC. either don't use it, or cooperate with it.
signature.asc
Description: PGP signature
