Unittests pass, and then an invalid memory operation happens after?
Liam McGillivray
yoshi.pit.link.mario at gmail.com
Thu Mar 28 03:56:10 UTC 2024
On Wednesday, 27 March 2024 at 22:14:16 UTC, H. S. Teoh wrote:
> What's the definition of this.map, this.faction, and
> this.currentTile?
As was said, and can be found on the linked repository, they are
references to class objects.
On Thursday, 28 March 2024 at 01:47:27 UTC, Steven Schveighoffer
wrote:
> On Wednesday, 27 March 2024 at 21:43:48 UTC, Liam McGillivray
> wrote:
>> `Unit` destructor:
>> ```
>> ~this() {
>> this.alive = false;
>> if (this.map !is null) this.map.removeUnit(this);
>> if (this.faction !is null)
>> this.faction.removeUnit(this);
>> if (this.currentTile !is null)
>> this.currentTile.occupant = null;
>> }
>> ```
>
> The GC does not guarantee destructor order. So this code is not
> valid -- e.g. you can't count on `map` to be a valid object at
> this point.
Well, this was originally done so that when I explicitly call
`destroy` on a Unit object (which happens in-game) it will delete
all references to itself.
Do you think it's better for me to move this code to a `die`
function that I can call instead, which will then call for it's
own destruction after running those function calls?
> The *only* thing you should be doing in a destructor is freeing
> non-GC resources.
>
>> I read that the garbage collector *sometimes* but not *always*
>> calls destructors on deletion, which sounds crazy to me.
>
> The GC is not guaranteed to delete memory or run destructors.
> In the current implementation, it will destroy everything at
> the end of the program that was allocated using the GC, but the
> language does not guarantee this.
What's strange is that even if I explicitly call `destroy` for
the only two objects at the end of the last unittest, it still
happens. I assumed that each unittest was like it's own program,
but I suppose not. It's deleting objects from an earlier
unittest, right?
I may be now starting to see why the use of a garbage collector
is such a point of contention for D. Not being able to predict
how the garbage collection process will happen seems like a major
problem.
> As mentioned, GCs do not work this way -- you do not need to
> worry about cascading removal of anything.
Wanting to avoid the GC pauses that I hear about, I was trying to
optimize object deletion so that the GC doesn't have to look for
every object individually. It sounds like what I'm hearing is
that I should just leave everything to the GC. While I can do
this without really hurting the performance of my program (for
now), I don't like this.
I hope that solving the unpredictable destruction pattern is a
priority for the developers of the language. This problem in my
program wouldn't be happening if either *all* of the objects had
their destructors called or *none* of them did.
Anyway, I suppose I'll have to experiment with either manually
destroying every object at the end of every unittest, or just
leaving more to the GC. Maybe I'll make a separate `die` function
for the units, if you think it's a good idea.
Also, check your Github notifications. I have something for you.
More information about the Digitalmars-d-learn
mailing list