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?