GC being too eager?

Paulo Pinto pjmlp at progtools.org
Fri Apr 11 04:25:15 PDT 2014


On Friday, 11 April 2014 at 09:32:29 UTC, Chris wrote:
> On Friday, 11 April 2014 at 06:51:01 UTC, Paulo Pinto wrote:
>> On Thursday, 10 April 2014 at 09:31:30 UTC, John Colvin wrote:
>>> On Thursday, 10 April 2014 at 09:24:51 UTC, Paulo Pinto wrote:
>>>> In a toy project I am working on with D v2.065, I came to 
>>>> the following situation:
>>>>
>>>> Node path = solver.find (map, start, end);
>>>> if (path !is null) {
>>>>  path.writeContents();  <-- Access Violation
>>>> }
>>>>
>>>> Apparently between the test and trying to use the class, the 
>>>> reference becomes null.
>>>>
>>>> Quite strange in a single threaded application.
>>>>
>>>> Any idea what might be happening or should I delve into 
>>>> assembly?
>>>>
>>>> --
>>>> Paulo
>>>
>>> Delve delve delve. Is this in an optimised build?
>>
>> I found out the cause, apparently std.container.Array destroys 
>> the memory used by reference types as well (e.g. classes).
>>
>> The small example below reproduces the error.
>>
>> Apparently the way Array manages the memory on its own 
>> invalidates the reference pointed by node, as I assume bad == 
>> node, but its memory is invalid.
>>
>> import std.stdio;
>> import std.container;
>>
>>
>> class Node {
>> }
>>
>> Node indentity (Node n)
>> {
>>    return n;
>> }
>>
>> Node badIndentity (Node n)
>> {
>>    Array!Node data;
>>    data.insert(n);
>>    return data.front();
>> }
>>
>> int  main(string[] args)
>> {
>>    auto node = new Node();
>>    auto n = indentity (node);
>>    writefln("Hello the address is %s", n);
>>    auto bad = badIndentity (node);
>>    writefln("Hello the address is %s", bad);
>>
>>    return 0;
>> }
>
> This reminds me of the question I had about the use of 
> appender. 
> (http://forum.dlang.org/thread/xfnvtlzyolmtncsmmqqi@forum.dlang.org)
>
> The internal memory management of containers and appender can 
> be the source of subtle bugs. For cases like your badIndentity 
> function, Objective-C has autorelease, so it's only released 
> when the program is done with the value.
> Out of interest, why would you write a function like 
> badIndentity this way? Or is it just a proof of concept?


This was only to show you how to reproduce the error.

On my application I use Array as a backing store for a BinaryHeap 
used to store the nodes that are available on the A* open list.

If this usage of Array is correct and the destroy method is 
misbehaving, I can create a bug for it.

I assume Array should manage its own memory but not touch the 
memory that belongs to reference types stored on it. At least the 
documentation doesn't say otherwise.

--
Paulo


More information about the Digitalmars-d-learn mailing list