Search code examples
arrayslazarusfreepascalsegmentation-fault

How to avoid SIGSEGV Errors on FPC compiler?


I'm currently having several problems with access violations in the program I'm building for my programming course. It is being build in pascal (the language used by the course) and using the Lazarus IDE (similar to Delphi but open).

As far as I know, Access Violations, or SIGSEGV errors, occurs when you try to use or address an invalid memory location. I've been trough a lot of these, specially when I wasn't declaring the length of dynamic arrays.

Now It seems I'm having this trouble with strings. (Or I might be derping with multi-dimensional arrays).

I'll paste only the procedure where the SIGSEGV is pointing, but the context is:

I have an array of integers and a multi-dimensional array containing it's power set (subconjuntos), the function where the error is poping (described below) is used to print this power set to a TextBox(indexed by local):

procedure writeSub(local: TEdit);
var
  i, j: integer;
begin
 for i:= 0 to High(subconjuntos)+1 do
   if Length(subconjuntos[i])>1 then
   begin
     local.Text:=local.Text+'[';
     for j:=0 to High(subconjuntos[i])+1 do local.Text:=local.Text+'('+IntToStr(subconjuntos[i][j])+') ';
     local.Text:=local.Text+'] ';
   end
   else local.Text:=local.Text+'['+IntToStr(subconjuntos[i][0])+'] '; {this is where I'm having the SIGSEG, the program wont compile if I don't reference it without the double brackets}
end;  

Any ideas why it is throwing SIGSEGV's?


Solution

  • Dynamic arrays have valid indices in the range low(arr) to high(arr) inclusive. And low(arr) is always zero for a dynamic array. You attempt to access an element with index high(arr)+1. That is off the end of the array and is certainly a mistake.

    Where you wrote

    for i:= 0 to High(subconjuntos)+1 do
    

    it should be

    for i:= 0 to High(subconjuntos) do
    

    or

    for i:= Low(subconjuntos) to High(subconjuntos) do
    

    and likewise for your other loop.

    On top of that, subconjuntos[i][0] is an out of bounds access if Length(subconjuntos[i]) is zero.

    If you enable range checking in the compiler options then the compiler will emit code to check the validity of each array access. Doing this will lead you more quickly to such errors.