Why am I getting segfaults when doing `foreach` with arrays of references?

Liam McGillivray yoshi.pit.link.mario at gmail.com
Sat Mar 9 06:29:45 UTC 2024


With [my game project](https://github.com/LiamM32/Open_Emblem), 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](https://github.com/LiamM32/Open_Emblem/blob/09505794970168c68ed5cffd9aa2ed69490ee80e/oe-raylib/source/mission.d)). 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](https://github.com/LiamM32/Open_Emblem/blob/master/source/map.d) 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?


More information about the Digitalmars-d-learn mailing list