On Thu, Feb 18, 2016 at 05:18:33PM -0800, Ali Çehreli via Digitalmars-d-learn wrote: > On 02/18/2016 12:12 PM, Ali Çehreli wrote: > > > > Hmm, why does the destructor of object 60 run in the middle of > > > nowhere? > > > > It so happens that the GC decides to collect when moving the array > > to a new location at that point. If you add the following to the > > beginning of main, you will see that the next object to destroy is > > 59, then 58, etc. > > > > import core.memory; > > GC.disable; > > > > So, everything makes sense other than throwing in a destructor > > having issues with the current GC. :-/ > > No, it doesn't make sense to me anymore. > > All we're doing here is growing an array. There shouldn't be any > destructor calls when just doing that, no? As the array grows, the > elements should be "moved" to the new location; why the destructor? I > hope this is related to the recent fix. [...]
Consider this: struct HasDtor { int data; ~this() { ... } } HasDtor[] func(HasDtor[] arr) { HasDtor[] middleSlice; for (i; 0 .. 1000) { arr ~= HasDtor(i); if (i == 500) { middleSlice = arr; } } return arr; } Suppose the array gets moved sometime after i=500 because it ran out of space in the current memory location. Since there is another slice middleSlice pointing at the old data, it's not just a matter of *moving* the elements over to the new location; they have to be *copied* over so that there are now two copies of the original elements -- the GC doesn't know whether func may try to access the original elements through middleSlice, so it cannot just move them. Only when middleSlice goes out of scope, can the old elements be destructed. So we see that when an array is grown, the elements cannot simply be moved to the new location; we must make copies of them, otherwise any slice of the old data will become invalid. So after an array is moved, there will be two copies of data, and if the original elements are unreferenced after all, the GC will call the dtors when it runs the next collection cycle. Then when the new elements become unreferenced, the dtors will be called again at the following collection cycle, on the new copies of the elements. T -- It always amuses me that Windows has a Safe Mode during bootup. Does that mean that Windows is normally unsafe?