Recent

Author Topic: Help with SIGSEGV errors  (Read 3882 times)

Dutrius

  • Newbie
  • Posts: 3
Help with SIGSEGV errors
« on: September 21, 2014, 09:01:28 pm »
Alright, I've been struggling with this code for over a week now and it has been driving me up a proverbial wall.

Basically, I'm using a system of classes for storing variables, but it seems that I can not create an instance of one of them properly, because when I try to access one of the variables, or call a destructor for the class, I get a segmentation fault.

This is the code (sorry for the length). The World class is the one that seems to be the problem:
Code: [Select]
unit WorldGen;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Dos;

type

  TTerrain=class
    LandType:string;
    Ruggedness:integer;
    Elevation:integer;
    ElevationType:string;
    IsFault,IsVolcano,HasRiver:boolean;
  end;

  TClimate=class
    PossibleTerrain:array[1..5] of string;
    ClimateTName,ClimateRName:string;
    Temperature,TempSeasonVar:real;
    Rain,RainSeasonVar:integer;
    DistFromCoast:integer;
    WindDir:integer;
    RainShadow:boolean;
    IsMonsoonal:boolean;
  end;

  TRegion=class
    Terrain:TTerrain;
    Territory:string;
    RegionName:string;
    Climate:TClimate;
    Lattitude:real;
    RegionalSav:integer;
  end;

  TContinent=class
    Region:array[1..225,1..225] of TRegion;
    ContinentName:string;
    CivsPresent:integer;
    Hemisphere:string;
    FaultType:string;
  end;

  TWorld=class
    NoOfRacesPresent:integer;
    WorldName:string;
    MinSavagery,MinEvil:integer;
    WorldSize:integer;
    Continent:array[1..5] of TContinent;
  end;

procedure WorldGeneration;

var
  World:TWorld;

implementation

uses
  MenuSystem,NameGen;

var
  ContinentTemp:TContinent;

procedure OceanBoundaries;
var
  i2,rx,ry,prob:integer;
begin
  for rx:=1 to 225 do
  begin
    ContinentTemp.Region[rx,1].Terrain.LandType:='ocean';
    ContinentTemp.Region[rx,225].Terrain.LandType:='ocean';
  end;
  for ry:=2 to 224 do
  begin
    ContinentTemp.Region[1,ry].Terrain.LandType:='ocean';
    ContinentTemp.Region[225,ry].Terrain.LandType:='ocean';
  end;
  for i2:=1 to 30 do
    for rx:=2 to 224 do
      for ry:=2 to 224 do
        begin
          prob:=0;
          if ContinentTemp.Region[rx-1,ry].Terrain.LandType='ocean' then
            prob:=prob+20;
          if ContinentTemp.Region[rx+1,ry].Terrain.LandType='ocean' then
            prob:=prob+20;
          if ContinentTemp.Region[rx,ry-1].Terrain.LandType='ocean' then
            prob:=prob+20;
          if ContinentTemp.Region[rx,ry+1].Terrain.LandType='ocean' then
            prob:=prob+20;
          if prob>(random(100)+1) then
            begin
              ContinentTemp.Region[rx,ry].Terrain.LandType:='ocean';
            end;
        end;
end;

procedure Faultlines(FaultDir:integer);
var
  i,rx,ry,prob,NewDir:integer;
begin
  prob:=random(4);
  case prob of
    0:begin
      rx:=1; //left
      ry:=random(195)+15;
      FaultDir:=3;
    end;
    1:begin
      rx:=225; //right
      ry:=random(195)+15;
      FaultDir:=7;
    end;
    2:begin
      ry:=1; //top
      rx:=random(195)+15;
      FaultDir:=5;
    end;
    3:begin
      ry:=225; //bottom
      rx:=random(195)+15;
      FaultDir:=1;
    end;
  end;
  ContinentTemp.Region[rx,ry].Terrain.IsFault:=TRUE;

  for i:=1 to 3 do         // this section moves the faultline away from the continent edge to prevent premature termination of the main loop
  begin
    prob:=random(24)+1;
    case prob of
      1..5:NewDir:=FaultDir-1;
      6..15:NewDir:=FaultDir;
      16..20:NewDir:=FaultDir+1;
    end;
    if NewDir=0 then NewDir:=8;
    if NewDir=9 then NewDir:=1;
    case NewDir of
      1:ry:=ry-1;
      2:begin
        rx:=rx+1;
        ry:=ry-1;
      end;
      3:rx:=rx+1;
      4:begin
        rx:=rx+1;
        ry:=ry+1;
      end;
      5:ry:=ry+1;
      6:begin
        rx:=rx-1;
        ry:=ry+1;
      end;
      7:rx:=rx-1;
      8:begin
        rx:=rx-1;
        ry:=ry+1;
      end;
    end;
    if (rx<1) or (ry<1) or (rx>225) or (ry>225) then
      break
    else
      ContinentTemp.Region[rx,ry].Terrain.IsFault:=TRUE;
  end;

  repeat                              // main faultline generation loop
    prob:=random(24)+1;
    case prob of
      1..2:NewDir:=FaultDir-2;
      3..7:NewDir:=FaultDir-1;
      8..17:NewDir:=FaultDir;
      18..22:NewDir:=FaultDir+1;
      23..24:NewDir:=FaultDir+2;
    end;
    if NewDir=0 then NewDir:=8;
    if NewDir=-1 then NewDir:=7;
    if NewDir=9 then NewDir:=1;
    case NewDir of
      1:ry:=ry-1;
      2:begin
        rx:=rx+1;
        ry:=ry-1;
      end;
      3:rx:=rx+1;
      4:begin
        rx:=rx+1;
        ry:=ry+1;
      end;
      5:ry:=ry+1;
      6:begin
        rx:=rx-1;
        ry:=ry+1;
      end;
      7:rx:=rx-1;
      8:begin
        rx:=rx-1;
        ry:=ry+1;
      end;
    end;
    if ((rx>0) and (rx<226)) and ((ry>0) and (ry<226)) then
      ContinentTemp.Region[rx,ry].Terrain.IsFault:=TRUE;
  until (rx=225) or (rx=1) or (ry=225) or (ry=1);      // this repeats until the continent edge has been hit

  prob:=random(10)+1;
  case prob of                                         // these affect the probability of volcanoes and earthquakes in surrounding regions.
    1..4:ContinentTemp.FaultType:='transform';
    5..6:ContinentTemp.FaultType:='subduction';
    7..9:ContinentTemp.FaultType:='convergant';
    10:ContinentTemp.FaultType:='divergant';
  end;
end;

function DistFromFault(rx:integer; ry:integer):real;
var
  x,x1,x2,y,y1,y2,rx2,ry2:integer;
  Distance:real;
begin
  if ContinentTemp.Region[rx,ry].Terrain.IsFault=FALSE then
  begin
    rx2:=rx;
    x1:=0;
    x2:=0;
    repeat
      x1:=x1+1;
      rx2:=rx2-1;
    until (rx2<2) or (ContinentTemp.Region[rx2,ry].Terrain.IsFault=TRUE);
    rx2:=rx;
    repeat
      x2:=x2+1;
      rx2:=rx2+1;
    until (rx2>224) or (ContinentTemp.Region[rx2,ry].Terrain.IsFault=TRUE);
    ry2:=ry;
    y1:=0;
    y2:=0;
    repeat
      y1:=y1+1;
      ry2:=ry2-1;
    until (ry2<2) or (ContinentTemp.Region[rx,ry2].Terrain.IsFault=TRUE);
    ry2:=ry;
    repeat
      y2:=y2+1;
      ry2:=ry2+1;
    until (ry2>224) or (ContinentTemp.Region[rx,ry2].Terrain.IsFault=TRUE);
    if x1<x2 then
      x:=x1
    else
      x:=x2;
    if y1>y2 then
      y:=y1
    else
      y:=y2;

    Distance:=sqrt(sqr(x)+sqr(y));

    DistFromFault:=Distance;
  end
  else
    DistFromFault:=0;
end;

procedure ElevationMesh;
var
  rx,ry,prob,RangeWidth:integer;
  Elevation:array[1..225,1..225] of integer;
  Dist:real;
begin
  {comments go in here}
  //create mesh
  for rx:=1 to 225 do
    for ry:=1 to 225 do
      if ContinentTemp.Region[rx,ry].Terrain.LandType='ocean' then
        Elevation[rx,ry]:=0
      else
        Elevation[rx,ry]:=5;
  //need mountains, hills and things

  RangeWidth:=random(11)+5;

  for rx:=1 to 225 do
    for ry:=1 to 225 do
    begin
      if ContinentTemp.Region[rx,ry].Terrain.IsFault=TRUE then
        if ContinentTemp.Region[rx,ry].Terrain.LandType<>'ocean' then
        case ContinentTemp.FaultType of
          'divergant':Elevation[rx,ry]:=random(200)+300;
          'convergant':Elevation[rx,ry]:=random(5500)+4000;
          'subduction':Elevation[rx,ry]:=random(3000)+1000;
          'transform':Elevation[rx,ry]:=random(50)+1;
        end
        else
        begin
          prob:=random(100)+1;
          if prob>90 then
            Elevation[rx,ry]:=random(100)+1
          else
            Elevation[rx,ry]:=0;
        end
      else
      begin
        Dist:=DistFromFault(rx,ry);
        if Dist<RangeWidth then
          case ContinentTemp.FaultType of
            'divergant':Elevation[rx,ry]:=trunc(((random(200)+300)*1.1)/Dist);
            'convergant':Elevation[rx,ry]:=trunc(((random(4000)+4000)*1.1)/Dist);
            'subduction':Elevation[rx,ry]:=trunc(((random(3000)+1000)*1.1)/Dist);
            'transform':Elevation[rx,ry]:=trunc(((random(300)+100)*1.1)/Dist);
          end
        else Elevation[rx,ry]:=Random(51);
      end;
    end;

  for rx:=1 to 225 do
    for ry:=1 to 225 do
      ContinentTemp.Region[rx,ry].Terrain.Elevation:=Elevation[rx,ry];

  for rx:=1 to 225 do
    for ry:=1 to 225 do
      case Elevation[rx,ry] of
        0:ContinentTemp.Region[rx,ry].Terrain.ElevationType:='open_water';
        1..38:ContinentTemp.Region[rx,ry].Terrain.ElevationType:='plain';
        39..499:ContinentTemp.Region[rx,ry].Terrain.ElevationType:='hill';
        500..2499:ContinentTemp.Region[rx,ry].Terrain.ElevationType:='foothill';
        2500..9500:ContinentTemp.Region[rx,ry].Terrain.ElevationType:='mountain';
      end;
end;

procedure RiverSystem;
var
  i,rx,ry,RiverDir,prob:integer;
  IsOcean:boolean;
  IsRiver:array[1..225,1..225] of boolean;
begin
  for rx:=1 to 225 do
    for ry:=1 to 225 do
      IsRiver[rx,ry]:=FALSE;
  for i:=1 to 50 do
  begin
    repeat
      rx:=random(225)+1;
      ry:=random(225)+1;
      if ContinentTemp.Region[rx,ry].Terrain.LandType='ocean' then
        IsOcean:=TRUE
      else
        IsOcean:=FALSE;
    until IsOcean=FALSE;
    RiverDir:=random(8)+1;
    repeat
      IsRiver[rx,ry]:=TRUE;
      prob:=random(9)+1;
      case prob of
        1:RiverDir:=RiverDir-2;
        2..3:RiverDir:=RiverDir-1;
        7..8:RiverDir:=RiverDir+1;
        9:RiverDir:=RiverDir+2;
      end;
      if RiverDir>8 then
        RiverDir:=RiverDir-8
      else if RiverDir<1 then
        RiverDir:=RiverDir+8;
      case RiverDir of
        1:ry:=ry-1;
        2:begin
          rx:=rx+1;
          ry:=ry-1;
        end;
        3:rx:=rx+1;
        4:begin
          rx:=rx+1;
          ry:=ry+1;
        end;
        5:ry:=ry+1;
        6:begin
          rx:=rx-1;
          ry:=ry+1;
        end;
        7:rx:=rx-1;
        8:begin
          rx:=rx-1;
          ry:=ry+1;
        end;
      end;
      if ContinentTemp.Region[rx,ry].Terrain.LandType='ocean' then
        IsOcean:=TRUE
      else
        IsOcean:=FALSE;
    until (IsOcean=TRUE) or (ContinentTemp.Region[rx,ry].Terrain.HasRiver=TRUE);
    for rx:=1 to 225 do
      for ry:=1 to 225 do
        ContinentTemp.Region[rx,ry].Terrain.HasRiver:=IsRiver[rx,ry];
  end;
end;

procedure ContinentSetup(N:integer);
var
  FaultDir,rx,ry:integer;
begin
  ContinentTemp:=TContinent.Create;
  for rx:=1 to 225 do
    for ry:=1 to 225 do
    begin
      ContinentTemp.Region[rx,ry]:=TRegion.Create;
      ContinentTemp.Region[rx,ry].Climate:=TClimate.Create;
      ContinentTemp.Region[rx,ry].Terrain:=TTerrain.Create;
    end;

  FaultDir:=0;

  OceanBoundaries;
  FaultLines(FaultDir);
  ElevationMesh;
  RiverSystem;

  World.Continent[N]:=ContinentTemp;

  for rx:=1 to 225 do
    for ry:=1 to 225 do
    begin
      World.Continent[N].Region[rx,ry]:=ContinentTemp.Region[rx,ry];
      World.Continent[N].Region[rx,ry].Climate:=ContinentTemp.Region[rx,ry].Climate;
      World.Continent[N].Region[rx,ry].Terrain:=ContinentTemp.Region[rx,ry].Terrain;
      ContinentTemp.Region[rx,ry].Climate.Destroy;
      ContinentTemp.Region[rx,ry].Climate:=Nil;
      ContinentTemp.Region[rx,ry].Terrain.Destroy;
      ContinentTemp.Region[rx,ry].Terrain:=Nil;
      ContinentTemp.Region[rx,ry].Destroy;
      ContinentTemp.Region[rx,ry]:=Nil;
    end;
  ContinentTemp.Destroy;
  ContinentTemp:=Nil;
end;

procedure SaveWorldAtGen;
var
  FName:text;
  DirPath,DirName,FStr:PathStr;
  WriteStr:string;
  rx,ry,I:integer;
begin
  DirName:='Games\'+World.WorldName;
  DirPath:=FSearch(DirName,GetEnv(''));
  if DirPath='' then
    CreateDir('Games\'+World.WorldName)
  else
  begin
    I:=1;
    repeat
      I:=I+1;
      DirName:='Games\'+World.WorldName+IntToStr(I);
      DirPath:=FSearch(DirName,GetEnv(''));
    until DirPath='';
    CreateDir(DirName);
  end;
  I:=0;
  for I:=1 to World.WorldSize do
  begin
    FStr:=DirName+'\Continent'+IntToStr(I);  //this is just for testing, will export continent name at later stage.
    Assign(FName,FStr);
    rewrite(FName); //start witing
    writeln(FName,'//Elevation:');
    for ry:=1 to 225 do
    begin
      for rx:=1 to 225 do
      begin
        //WriteStr:=IntToStr(World.Continent[I].Region[rx,ry].Terrain.Elevation);  //this line produces a segmentation fault
        //write(FName,WriteStr);
        write(FName,',');
      end;
      writeln(FName,'');
    end;
    Close(FName);   //end writing
  end;
end;

procedure WorldParameters;
begin
  if Form1.ContNoCombo.Text<>'Random' then
    World.WorldSize:=StrToInt(Form1.ContNoCombo.Text)
  else
    World.WorldSize:=random(5)+1;

  World.WorldName:=Form1.WorldNameEdit.Text;

  //temp
  //World.WorldSize:=1;
end;

procedure WorldGeneration;
var
  N,rx,ry:integer;
begin
  World:=Nil;
  World:=TWorld.Create;
  for N:=1 to 5 do
  begin
    World.Continent[N]:=TContinent.Create;
    for rx:=1 to 225 do
      for ry:=1 to 225 do
      begin
        World.Continent[N].Region[rx,ry]:=TRegion.Create;
        World.Continent[N].Region[rx,ry].Climate:=TClimate.Create;
        World.Continent[N].Region[rx,ry].Terrain:=TTerrain.Create;
      end;
  end;

  WorldParameters;

  For N:=1 to World.WorldSize do
  begin
    ContinentSetup(N);
  end;

  SaveWorldAtGen;

  for N:=1 to 5 do
  begin
    for rx:=1 to 225 do
      for ry:=1 to 225 do
      begin
        World.Continent[N].Region[rx,ry].Climate.Destroy;
        World.Continent[N].Region[rx,ry].Terrain.Destroy;
        World.Continent[N].Region[rx,ry].Destroy;
        World.Continent[N].Region[rx,ry].Climate:=Nil;
        World.Continent[N].Region[rx,ry].Terrain:=Nil;
        World.Continent[N].Region[rx,ry]:=Nil;
      end;
    World.Continent[N].Destroy;
    World.Continent[N]:=Nil;
  end;
  World.Destroy;
  World:=Nil;
end;

end.

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Help with SIGSEGV errors
« Reply #1 on: September 21, 2014, 09:17:03 pm »
Quick off the cuff remark - you're calling .Destroy; instead call .Free;   

Go on, ask me why?  Good question...   Errr...  It's just what we do?  Just looked in the code, and the only difference appears to be a little safety factor...
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Help with SIGSEGV errors
« Reply #2 on: September 21, 2014, 09:33:42 pm »
When you step through the code, exactly which line gives you the first segmentation fault?  I doubt very much it's on that first World := TWorld.Create; can't see a problem there...

I note there's no safety code in here - if you call WorldParameters before WorldGeneration for instance, you're definitely going to have problems.  Again, this shouldn't be a problem as I *think* you're initialising everything in the right order.

You're going to have problems here (but this is at the end of the run)
Code: [Select]
        World.Continent[N].Region[rx, ry].Climate.Destroy;
        World.Continent[N].Region[rx, ry].Terrain.Destroy;
        World.Continent[N].Region[rx, ry].Destroy;
        World.Continent[N].Region[rx, ry].Climate := nil;  //<--- AV as Region[rx, ry] has been free'd, don't try to call it's .Climate, even to set that to nil;
        World.Continent[N].Region[rx, ry].Terrain := nil;  //<--- AV as Region[rx, ry] has been free'd, don't try to call it's .Terrain, even to set that to nil;
        World.Continent[N].Region[rx, ry] := nil;   

Rearrange the above like so...

Code: [Select]
        World.Continent[N].Region[rx, ry].Climate.Free;
        World.Continent[N].Region[rx, ry].Climate := nil;
        World.Continent[N].Region[rx, ry].Terrain.Free;
        World.Continent[N].Region[rx, ry].Terrain := nil;
        World.Continent[N].Region[rx, ry].Free;
        World.Continent[N].Region[rx, ry] := nil;

Alternatively
Code: [Select]
        FreeandNil(World.Continent[N].Region[rx, ry].Climate);
        FreeandNil(World.Continent[N].Region[rx, ry].Terrain);
        FreeandNil(World.Continent[N].Region[rx, ry]);

You're also going to have problems if Form1.ContNoCombo.Text contains a value outside of '1'..'5'.

And you're also going to have problems if Form1 hasn't been created yet, but again I doubt that.

Let us know the exact line you have the problems with, and we'll give you more specific advice :-)
 (with all those for loops, I'd use breakpoints rather than stepping through the code...)
« Last Edit: September 21, 2014, 09:37:16 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

Dutrius

  • Newbie
  • Posts: 3
Re: Help with SIGSEGV errors
« Reply #3 on: September 21, 2014, 09:45:19 pm »
As it currently stands, the error occurs at World.Continent[N].Region[rx,ry].Climate.Destroy;

I tried putting in the nil operators out of desperation, really.

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Help with SIGSEGV errors
« Reply #4 on: September 21, 2014, 10:02:35 pm »
Switch to .free's and see what happens.

Also, enable HeapTrace (Project Options - Debugging - Other debugging info - "Use Heaptrc unit").  If the .free;s work and you get to close the app correctly, heaptrace will let you know if there any memory leaks in your code.
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Help with SIGSEGV errors
« Reply #5 on: September 21, 2014, 10:07:44 pm »
You're also doing something odd in ContinentSetup, and this will definitely give you problems, in fact, I think this is your problem...

Code: [Select]
      World.Continent[N].Region[rx,ry]:=ContinentTemp.Region[rx,ry];
      World.Continent[N].Region[rx,ry].Climate:=ContinentTemp.Region[rx,ry].Climate;
      World.Continent[N].Region[rx,ry].Terrain:=ContinentTemp.Region[rx,ry].Terrain;
      ContinentTemp.Region[rx,ry].Climate.Destroy;
      ContinentTemp.Region[rx,ry].Climate:=Nil;
      ContinentTemp.Region[rx,ry].Terrain.Destroy;
      ContinentTemp.Region[rx,ry].Terrain:=Nil;
      ContinentTemp.Region[rx,ry].Destroy;
      ContinentTemp.Region[rx,ry]:=Nil;

Rearrange the above to

Code: [Select]
      FreeandNil(World.Continent[N].Region[rx, ry].Climate);
      FreeandNil(World.Continent[N].Region[rx, ry].Terrain);
      FreeandNil(World.Continent[N].Region[rx, ry]);
      World.Continent[N].Region[rx,ry]:=ContinentTemp.Region[rx,ry];

and I think your woes will be over...   

(You don't need to individually set the .Climate and .Terrain from the Temp, they'll come across automatically, and before you were freeing the Temp object, not the original object in the array.)

« Last Edit: September 21, 2014, 10:09:19 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Help with SIGSEGV errors
« Reply #6 on: September 21, 2014, 10:08:26 pm »
The problem is not one of syntax, but of scale.
You're trying to stuff too much into memory at one time.
TRegion has an instancesize of 40, TClimate of 72, TTerrain of 24, totalling 136 bytes. Each class has string and other data, and the class overhead itself so the actual memory footprint of a TRegion might be say 200 bytes.
You set up a 255x255 array of these, i.e. perhaps something around 13,005,000.
Each world has 5 such continents -> 65,025,000.
You may have several worlds...
Why are you surprised that trying to shoehorn all this into memory fails?

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Help with SIGSEGV errors
« Reply #7 on: September 21, 2014, 10:14:57 pm »
Your problem is in ContinentSetup:
Code: [Select]
  ContinentTemp:=TContinent.Create;
...
  World.Continent[N]:=ContinentTemp; <---- You are destroying this later
...
  ContinentTemp.Destroy;

rvk

  • Hero Member
  • *****
  • Posts: 6112
Re: Help with SIGSEGV errors
« Reply #8 on: September 21, 2014, 10:15:29 pm »
Maybe i'm wrong... but....
You're doing an
Code: [Select]
World.Continent[N].Region[rx,ry].Climate:=TClimate.Create;
at the beginning of your main procedure.

Later in ContinentSetup your doing this:
Code: [Select]
ContinentTemp.Region[rx,ry].Climate:=TClimate.Create;
...
World.Continent[N].Region[rx,ry].Climate:=ContinentTemp.Region[rx,ry].Climate;
...
ContinentTemp.Region[rx,ry].Climate.Destroy;

As i see it you create an object Climate in the continents (in the main procedure). And in ContinentSetup your doing a second Climate.Create in a temporary object but you assign this object to the Wold.Continent. And right after you destroy that temporary Climate. At that moment the World.Continent.Climate contains an invalid Climate (which you destoryed). Also the original Climate you created in your main procedure is lost because you reassigned the variable without destroying that one.

As i see it you don't need to do the creates in your ContinentSetup because you've already done them in your main procedure.

Or you should remove the one from the main-procedure (because you used the temp everywhere) and remove the destroy of that temp in the ContinentSetup.

Dutrius

  • Newbie
  • Posts: 3
Re: Help with SIGSEGV errors
« Reply #9 on: September 21, 2014, 10:23:10 pm »
Thanks for the help guys, I'll try to sort it out as soon as I can.

eny

  • Hero Member
  • *****
  • Posts: 1634
Re: Help with SIGSEGV errors
« Reply #10 on: September 22, 2014, 06:18:10 pm »
Everything will be easier to manage if you make use of encapsulation.
Create constructors and destructors for each class, and do the creation and destruction of the composed classes in there.
Use array properties in such a way that you can call e.g. Region[rx,ry].FreeClimate; FreeClimate then frees the actual Climate instance and sets the internal Climate reference to nil.
The same applies to Region etc.
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

 

TinyPortal © 2005-2018