GC being too eager?
Steven Schveighoffer
schveiguy at yahoo.com
Fri Apr 11 05:26:16 PDT 2014
On Fri, 11 Apr 2014 07:25:15 -0400, Paulo Pinto <pjmlp at progtools.org>
wrote:
> 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.
This is a side effect of classes being first-class reference types. Array
needs to call destroy on structs, but not on classes. Sort of a "shallow
destroy."
It's an interesting bug.
-Steve
More information about the Digitalmars-d-learn
mailing list