[SOLVED] Graph returns a SIGSEVG after calling custom 'Draw' function lazarus / 39-Graphics ---------------------------------------------------------------------- mug33n · 2024-11-12 14:17 Hello, i have the problem with this code (it raises a SIGSEVG (see problem.png) in Lazarus): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODE objfpc} {$H+} {$J-} {$R+} {$UNITPATH src}program Main; uses cthreads, ptcGraph, ptcCrt, UMenu; var Menu: TMenu;   Mode, Driver: SmallInt; begin   Mode := M800x600; Driver := D16Bit;   InitGraph(Driver, Mode, '');    Menu := TMenu.Init(3, 1, 'TEST');    Menu.Draw(16, 16, 16, White, ['WEE', 'WEE', 'WEE']);    CloseGraph;end.  It says that the problem is a call for Menu.Draw from UMenu unit (see reason.png). The code of UMenu unit: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODE objfpc} {$H+} {$J-} {$R+}unit UMenu; interface   uses cthreads, ptcGraph;    type TMenu = class         EntryCount, Font: SmallInt;       Title: String;         Texts: Array of String;         PosX, PosY: Array of SmallInt;                  constructor Init(EC, F: SmallInt; T: String = 'TEST');          procedure Draw(SX, SY, Step, Color: SmallInt: ColorType; T: Array of String);   end; implementation   constructor TMenu.Init(EC, F: SmallInt; T: String = 'TEST');   begin      if EC = 0 then EC := 1;      if F = 0 then F := 0;         EntryCount := EC; Font := F; Title := T;       SetLength(Texts, EntryCount);      SetLength(PosX, EntryCount); SetLength(PosY, EntryCount);   end;    procedure TMenu.Draw(SX, SY, Step, Color: SmallInt; T: Array of String);   var I: Integer;          Temp: OutTextXYProc;    begin                if Length(T) = 0 then RunError(10);      if (Length(T) > EntryCount) or (Length(T) < EntryCount) then RunError(11);       { Set text color and font }      SetColor(Color); SetTextStyle(Font, 0, 0);       { Display menu title }                OutTextXY(SX, SY, Title);                 Inc(SY, Step);       { Display menu entries }      for I := 1 to EntryCount do      begin         PosX[I] := SX; PosY[I] := SY;         Texts[I] := T[I];                  OutTextXY(PosX[I], PosY[I], Texts[I]);        Inc(SY, Step);      end;   end;end.  I use the following versions of software to build the project: FPC version - 3.2.2 from Gentoo GNU/Linux official repository; Lazarus version - 3.6, built from source code. P.S. - Thanks to rvk for help. ---------------------------------------------------------------------- TRon · 2024-11-12 14:20 Hi mug33n, You seem to be mixing old-style objects with a class. Either tmenu is a class or an old style object. try Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  type TMenu = object // not class         EntryCount, Font: SmallInt;         Title: String;         Texts: Array of String;         PosX, PosY: Array of SmallInt;                  constructor Init(EC, F: SmallInt; T: String = 'TEST');          procedure Draw(SX, SY, Step, Color: SmallInt: ColorType; T: Array of String);   end; ---------------------------------------------------------------------- rvk · 2024-11-12 14:31 Although I do have questions about the old-style object... why are you using those???? The problem lies somewhere else. You have several  Array of xx; You do a SetLength on that Array. After that you do a for loop with 1 to count. But... array of x is always from index 0 !!! So you need to do 0 to count - 1 (or access object[I - 1] instead of object[ I ] ) ---------------------------------------------------------------------- TRon · 2024-11-12 14:37 Ah yes rvk you are right. As a quick dirty fix from Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i EntryCount := EC; Font := F; Title := T;...for I := 1 to EntryCount do to Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i EntryCount := EC+1; Font := F; Title := T;...for I := 1 to EntryCount-1 do  Only for quick testing of course  Better: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for i := low(your_array) to high(your_array) ---------------------------------------------------------------------- mug33n · 2024-11-12 15:04 Quote from: rvk why are you using those???? Are You about usage of ptcGraph instead of other tools? Quote from: rvkYou do a SetLength on that Array. After that you do a for loop with 1 to count. But... array of x is always from index 0 !!! So you need to do 0 to count - 1 (or access object[I - 1] instead of object[ I ] ) I tried to do that by replacing 47th line in UMenu on this one (i'm not sure what i understand this part of Your answer correctly), but it still fails with SIGSEGV: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for I := 0 to EntryCount do ---------------------------------------------------------------------- rvk · 2024-11-12 15:13 Quote from: mug33n on November 12, 2024, 04:04:23 pmQuote from: rvk why are you using those???? Are You about usage of ptcGraph instead of other tools?No, I'm talking about the contructor Init(). I haven't seen that since my good ol' Borland Pascal years. Quote from: mug33n on November 12, 2024, 04:04:23 pmQuote from: rvkYou do a SetLength on that Array. After that you do a for loop with 1 to count. But... array of x is always from index 0 !!! So you need to do 0 to count - 1 (or access object[I - 1] instead of object[ I ] ) I tried to do that by replacing 47th line in UMenu on this one (i'm not sure what i understand this part of Your answer correctly), but it still fails with SIGSEGV: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i for I := 0 to EntryCount doYou can't go to EntryCount. If you use Array of X you end up with an array [0..EntryCount - 1] !! So you can't loop to EntryCount but you need to loop to EntryCount - 1. But you then also need to make sure you fill those correctly. You could go the 'dirty' way TRon already mentioned and do SetLength ( EntryCount + 1). But that will give you Array[ 0 .. EntryCount ] and then you have a 0 entry which you don't use. For testing this is fine but it's best you learn how to use dynamic arrays and you need to know they start on 0 up to (and NOT including) the count you gave. SetLength(Count) reserves Count elements. That's [0 .. Count - 1] (you see that?) Doing SetLength(Count + 1) will reserve Count + 1 elements. And then you have [0 .. Count ] (and you can use that [ Count ] but have a  [ 0 ] which you don't use. That's how dynamic arrays work ---------------------------------------------------------------------- TRon · 2024-11-12 15:15 A slightly other approach (I tried to stay in line with your original as much as possible) as there were many other small things not exactly right. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Main; {$MODE objfpc} {$H+} {$J-} {$R+} uses  {$ifdef linux}  cthreads,  {$endif}  ptcgraph, ptccrt, umenu; var  Menu   : TMenu;  Mode   : SmallInt;  Driver : SmallInt; begin   Mode   := M800x600;   Driver := D16Bit;   InitGraph(Driver, Mode, '');    Menu.Init(3, 1, 'TEST');    Menu.Draw(16, 16, 16, White, ['WEE', 'WEE', 'WEE']);   repeat   until keypressed;    CloseGraph;end.  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit UMenu; {$MODE objfpc} {$H+} {$J-} {$R+} interface uses  {$ifdef linux}  cthreads,  {$endif}  ptcGraph; type  TMenuItem = record    // if wanted/required add fields xpos and ypos here as well.    FTitle : string;  end;   TMenu = object // class    FFont : SmallInt;    FTitle: String;    FMenuItems : array of TMenuItem;    constructor Init(EC, F: SmallInt; const T: String = 'TEST');    procedure Draw(SX, SY, Step, Color: SmallInt; T: Array of String);  end; implementation constructor TMenu.Init(EC, F: SmallInt; const T: String = 'TEST');begin  SetLength(FMenuItems, EC);  FFont  := F;  FTitle := T;end;  procedure TMenu.Draw(SX, SY, Step, Color: SmallInt; T: Array of String);var  i : integer;  Title: string;begin  // copy title  i := low(FMenuItems);  for Title in T do  begin    if i < length(FMenuItems)      then FMenuItems[i].FTitle := Title      else break;    inc(i);  end;    { Set text color and font }  SetColor(Color);  SetTextStyle(FFont, 0, 0);   { Display menu title }  OutTextXY(SX, SY, FTitle);    { Display menu entries }  for I := low(FMenuItems) to high(FMenuItems) do  begin    Inc(SY, step);    OutTextXY(SX, SY, FMenuItems[I].FTitle);  end;end; end. ---------------------------------------------------------------------- mug33n · 2024-11-12 15:53 Quote from: rvk on November 12, 2024, 04:13:37 pmNo, I'm talking about the contructor Init(). I use because it seems more familiar (?) for me then Create. Quote from: rvk on November 12, 2024, 04:13:37 pmSo you can't loop to EntryCount but you need to loop to EntryCount - 1. Thank You!