With my game project, I have been getting segmentation faults that are unexplainable at my knowledge level. They seem to happen when doing a "foreach" loop through an array of references.
Skip to the bolded text if you don't want to read too much, as I found a way around the first example.
Prior to the latest commit, I had this "foreach" loop lines starting at oe-raylib/source/mission.d:214 (see file). It would segfault on the second line shown here:
foreach (startTile; this.startingPoints) {
startTile.occupant.map = this;
writeln("Just assigned Unit.map to the Mission object.");
this.factionUnits["player"] ~= *startTile.occupant;
}
This was in the Mission class (a derivative of Map), which this would be a reference to. startTile is an instance of the GridTile struct, which contains a reference to a Tile object called tile. The Tile object had a pointer to a Unit object called occupant. GridTile.occupant is a convenience function that's equivalent to GridTile.tile.occupant. Finally, the Unit class contains a reference to a Map object called map. Because Mission is a derived class, a Mission object can also fit. All of the things being accessed were public.
I thought the problem was that it was looking in Tile objects with occupant being null, but changing line 214 to the following didn't solve it.
foreach (startTile; this.startingPoints) if (startTile.occupant !is null) {
Current example
I ended up getting rid of that line causing the segmentation fault and achieving the desired functionality a different way, but now I get a similar one later in the program.
The turnReset function in my Map class does a 'foreach' loop through an array of Unit objects:
void turnReset() {
foreach(unit; this.allUnits) {
unit.turnReset;
}
}
My program successfully completed one cycle of the loop, but segfaulted with the second one. I found in GDB that for the second object it didn't even reach the first line in Unit.turnReset(). This may imply that the array length of Map.allUnits is more than one, but no object has been assigned to allUnits[1]. However, there are no lines anywhere in my code that changes the length of this array without appending. I tried doing the grep -r allUnits command to look for every mention of this array in my code, and here is what I have:
source/map.d: public Unit[] allUnits;
source/map.d: foreach (unit; this.allUnits) {
source/map.d: foreach(unit; this.allUnits) {
source/map.d: assert (canFind(map.allUnits, unit));
source/unit.d: if (this in map.allUnits) {
oe-raylib/source/mission.d: this.allUnits ~= *startTile.occupant;
oe-raylib/source/mission.d: foreach (unit; this.allUnits) {
oe-raylib/source/mission.d: if (addToMap) allUnits ~= newUnit;
oe-raylib/source/mission.d: foreach (unit; mission.allUnits) {
oe-raylib/source/mission.d.bak2: foreach (unit; this.allUnits) {
As far as I see, there's no way that the allUnits array would be longer than the number of objects that have been added to it, so why would calling a public function of one of it's members cause a segfault?
Permalink
Reply