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?
  • Why am I getting... Liam McGillivray via Digitalmars-d-learn
    • Re: Why am ... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
      • Re: Why... Liam McGillivray via Digitalmars-d-learn
        • Re:... Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
        • Re:... Liam McGillivray via Digitalmars-d-learn

Reply via email to