Recent

Author Topic: [Solved] Strange error on loop  (Read 966 times)

nikel

  • Sr. Member
  • ****
  • Posts: 267
[Solved] Strange error on loop
« on: November 14, 2023, 02:49:31 pm »
Hello, I'm trying to detect if two strings contain some string. Here's my code:

Code: Pascal  [Select][+][-]
  1. function TForm1.IsEmptyDirectory(Index: Integer): Boolean;
  2. var
  3.   I          : Integer;
  4.   J          : Integer;
  5.   List       : TStringList;
  6.  
  7. procedure IsEmptyDirectoryUnset;
  8. begin
  9.   I:=0;
  10.   J:=0;
  11.   List.Free;
  12.   Exit;
  13. end;
  14. begin
  15.   I:=0;
  16.   J:=0;
  17.  
  18.   List:=TStringList.Create;
  19.   List.Sorted:=False;
  20.   List.LoadFromFile(Path);
  21.  
  22.   if (Index >= List.Count - 1) or (List[Index] = '') then
  23.   begin
  24.     Result:=False;
  25.     IsEmptyDirectoryUnset;
  26.   end;
  27.  
  28.  
  29.  
  30.   while I <= List[Index].Length - 4 do
  31.   begin
  32.     if ((List[Index].SubString(I, 4) = '+---') or (List[Index].SubString(I, 4) = '\---')) then
  33.     begin
  34.       J:=0;
  35.  
  36.       while (J <= List[Index + 1].Length - 4) do
  37.       begin
  38.         if (List[Index + 1].SubString(J, 4) = '+---') or (List[Index + 1].SubString(J, 4) = '\---') then
  39.         begin
  40.  
  41.           Result:=True;
  42.           IsEmptyDirectoryUnset;
  43.           Break;
  44.           Exit;
  45.         end;
  46.  
  47.         J:=J + 4;
  48.       end;
  49.     end;
  50.  
  51.     I:=I + 4;
  52.   end;
  53.  
  54.   Result:=False;
  55.  
  56.   IsEmptyDirectoryUnset;
  57. end;

This is giving me an error. I attached a screenshot. Can anyone help me?

« Last Edit: November 14, 2023, 03:17:00 pm by nikel »

Zvoni

  • Hero Member
  • *****
  • Posts: 3191
Re: Strange error on loop
« Reply #1 on: November 14, 2023, 02:54:21 pm »
Line 20: Where is "Path" coming from?

Line 12: The "Exit" jumps out of the (nested) procedure, not the function.
So, basically, if you pass an invalid index, your code continues on, and tries to access an invalid Index of List.

It's the reason, why i use (nested) Functions instead of procedures for unexpected cleanup

Aircode
Code: Pascal  [Select][+][-]
  1. Function IsEmptyDirectoryUnset:Boolean;
  2. begin
  3.   I:=0;
  4.   J:=0;
  5.   List.Free;
  6.   Result:=True;
  7. end;
  8. .
  9. .
  10. .
  11. .
  12. //For your Lines 22 to 26
  13. if (Index >= List.Count - 1) or (List[Index] = '') then
  14.      If IsEmptyDirectoryUnset Then Exit(False);
  15.  
  16.  

Line 43 + 44:
Break followed by Exit??
huh?
With Break you jump out of the Loop.... Exit gets never executed....
« Last Edit: November 14, 2023, 03:01:50 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Fibonacci

  • Hero Member
  • *****
  • Posts: 788
  • Internal Error Hunter
Re: Strange error on loop
« Reply #2 on: November 14, 2023, 03:02:04 pm »
On line 43 you break the loop ("exit" is unrechable), and the loop from line 30 continues

On line 41 you set result to true, break the loop, but again loop from line 30 continues, and after it finishes result will be set to false on line 54

This whole code looks broken

rvk

  • Hero Member
  • *****
  • Posts: 6910
Re: Strange error on loop
« Reply #3 on: November 14, 2023, 03:02:26 pm »
On one hand do you check on line 22 if Index is out of range of List.Count.

But on the other hand... if that's the case you STAY in that procedure and the line 30 List[Index].Lengte will crash because Index is out of range of the List array.

So put an exit after IsEmptyDirectoryUnset;

Second... you call Exit on line 12 inside the procedure IsEmptyDirectoryUnset, but that doesn't do anything. It will exit the current procedure, NOT the procedure that called it (see remark above).

About the List.Free; in IsEmptyDirectoryUnset, it might be better that you use try/finally construct. This is much better than calling IsEmptyDirectoryUnset (because I see you also call it multiple times). So remove that subdirectory and create a propper try/finally structure.
« Last Edit: November 14, 2023, 03:05:43 pm by rvk »

nikel

  • Sr. Member
  • ****
  • Posts: 267
Solved: Strange error on loop
« Reply #4 on: November 14, 2023, 03:14:59 pm »
Thanks for the replies. Zvoni, Fibonacci and rvk. I put "Exit" after unset and worked fine. Also I'm planning to use "try / finally".

rvk

  • Hero Member
  • *****
  • Posts: 6910
Re: [Solved] Strange error on loop
« Reply #5 on: November 14, 2023, 03:59:47 pm »
Without actually knowing what it does... you could restructure your code like this:
(with the try/finally, even with exit, the finally part is always executed)

Code: Pascal  [Select][+][-]
  1. function TForm1.IsEmptyDirectory(Idx: integer): boolean;
  2. var
  3.   I: integer;
  4.   J: integer;
  5.   List: TStringList;
  6. begin
  7.   Result := False; // Default result
  8.   I := 0;
  9.   J := 0;
  10.  
  11.   List := TStringList.Create;
  12.   try
  13.     List.Sorted := False;
  14.     List.LoadFromFile(Path);
  15.  
  16.     if (Idx >= List.Count - 1) or (List[Idx] = '') then
  17.       Exit(False); // Result := False and exit
  18.  
  19.     while I <= List[Idx].Length - 4 do
  20.     begin
  21.       if ((List[Idx].SubString(I, 4) = '+---') or (List[Idx].SubString(I, 4) = '\---')) then
  22.       begin
  23.         J := 0;
  24.  
  25.         while (J <= List[Idx + 1].Length - 4) do
  26.         begin
  27.           if (List[Idx + 1].SubString(J, 4) = '+---') or (List[Idx + 1].SubString(J, 4) = '\---') then
  28.             Exit(True); // same as Result := true and exit
  29.           J := J + 4;
  30.         end;
  31.       end;
  32.  
  33.       I := I + 4;
  34.     end;
  35.  
  36.   finally
  37.     List.Free;
  38.   end;
  39.  
  40. end;
« Last Edit: November 14, 2023, 04:01:59 pm by rvk »

 

TinyPortal © 2005-2018