Recent

Author Topic: For loop jumps about, data is corrupted...  (Read 469 times)

ranny

  • New Member
  • *
  • Posts: 39
For loop jumps about, data is corrupted...
« on: August 13, 2019, 04:11:51 pm »
Hi,

I am working on a spline routine that I was moving from one program to another.  Works perfectly in original program but fails in the new one.  In the loop for "i:=2 to gap do", if I step through it it jumps from i=2, up to gap:=n-1 (which is 48 in value), then back into the loop where i=48 and continues to do this repeatedly, I assume 48 times.  All the caluclations are wrong values.  Note I am passing arrays into the procedure and also I am using global array such as c[] and d[]..

I don't know why it works fine in one program and not in this one.

Here is the part of the code:-

Code: Pascal  [Select]
  1. procedure newspline(var x:array of single;var y:array of single;var n:integer);
  2.  
  3.      var
  4.     i,j,gap:integer;
  5.     h:double;
  6.     begin
  7.     gap:=n-1;
  8.     //! check input
  9.     //if ( n < 2 ) return
  10.     //if ( n < 3 ) then
  11.     //b(1) = (y(2)-y(1))/(x(2)-x(1))   ! linear interpolation
  12.     //c(1) = 0.
  13.     //d(1) = 0.
  14.     //b(2) = b(1)
  15.     //c(2) = 0.
  16.     //d(2) = 0.
  17.     //return
  18.     //end if
  19.  
  20.     //step 1: preparation
  21.     d[1]:=x[2]-x[1];
  22.     c[2]:=(y[2]-y[1])/d[1];
  23.     for i:=2 to gap do    //do i = 2, gap
  24.         begin
  25.         d[i]:=x[i+1]-x[i];
  26.         b[i]:=2.0*(d[i-1]+d[i]);
  27.         c[i+1]:=(y[i+1]-y[i])/d[i];
  28.         c[i]:=c[i+1]-c[i];
  29.         end;


wp

  • Hero Member
  • *****
  • Posts: 6459
Re: For loop jumps about, data is corrupted...
« Reply #1 on: August 13, 2019, 04:18:34 pm »
When you work with an "array of single" the indexes are 0-based, i.e. the first value is at index 0 and the last one at index n (with n being the array length). In your code, however, I never see an index 0, only 1. Therefore, I suspect that your code assumes a 1-based array which runs out of bounds when you access the last array element.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

howardpc

  • Hero Member
  • *****
  • Posts: 3200
Re: For loop jumps about, data is corrupted...
« Reply #2 on: August 13, 2019, 04:28:14 pm »
As wp writes, array-based routines that give unexpected results can nearly always be traced to invalid index values at one end of the array or the other.
If you have range-checking turned on such errors are immediately apparent.
For reliable help with debugging  programs that are more than a few score lines of code, a compilable example is required. Otherwise your readers can only guess at the code they don't see, which is frustrating, and often counter-productive, because others will make comments that are not relevant only because hidden, vital information is not shown, and assumptions have been made that would never have been made otherwise.

Thaddy

  • Hero Member
  • *****
  • Posts: 9278
Re: For loop jumps about, data is corrupted...
« Reply #3 on: August 13, 2019, 05:26:00 pm »
And why do you do not use High(<array>). The gap is a stop-gap.
Also note I would declare a :
Code: Pascal  [Select]
  1. type TSingleArray = array of single;
  2. procedure newspline(var x, y:TSingleArray;var n:integer);// can possibly drop n...because of high()
  3.  

I think it can be rewritten as:
Code: Pascal  [Select]
  1. {$mode objfpc}
  2. type TSingleArray = array of single;
  3. procedure newspline(var x, y:TSingleArray);// can possibly drop n...because of high(), not sure.
  4. begin
  5. if SizeOf(x) = SizeOf(y) then
  6. ;//process here and use high()
  7. end;
  8.  
  9. begin
  10. end.
« Last Edit: August 13, 2019, 05:34:00 pm by Thaddy »
also related to equus asinus.

julkas

  • Sr. Member
  • ****
  • Posts: 430
  • KISS principle / Lazarus 2.0.0 / FPC 3.0.4
Re: For loop jumps about, data is corrupted...
« Reply #4 on: August 13, 2019, 07:35:46 pm »
And why do you do not use High(<array>). The gap is a stop-gap.
Also note I would declare a :
Code: Pascal  [Select]
  1. type TSingleArray = array of single;
  2. procedure newspline(var x, y:TSingleArray;var n:integer);// can possibly drop n...because of high()
  3.  

I think it can be rewritten as:
Code: Pascal  [Select]
  1. {$mode objfpc}
  2. type TSingleArray = array of single;
  3. procedure newspline(var x, y:TSingleArray);// can possibly drop n...because of high(), not sure.
  4. begin
  5. if SizeOf(x) = SizeOf(y) then
  6. ;//process here and use high()
  7. end;
  8.  
  9. begin
  10. end.
if SizeOf(x) = SizeOf(y) will be always True.
procedure mulu64(a, b: QWORD; out clo, chi: QWORD); assembler;
asm
  mov rax, a
  mov rdx, b
  mul rdx
  mov [clo], rax
  mov [chi], rdx
end;

ranny

  • New Member
  • *
  • Posts: 39
Re: For loop jumps about, data is corrupted...
« Reply #5 on: August 14, 2019, 09:08:57 am »
Thanks for all the comments.  I still have plenty to learn but I remain confused regarding the array size definition.

In this case all arrays are dimensioned in calling routines or are global.  As the program can handle differing no of pieces of data to solve, they have plenty of room.  In this example, n=49 but the high of x[], y[], n[n] and c[] and d[] is 200.  They are dimensioned from 0..200 and 0 is never called, and 200 will never be reached.  I would also have thought if the arrays were out of range I would get an error but I don't.  All of this worked without error in another program with the arrays dimensioned as above, no changes to the calling routines or the routines in question and both are compiled on the same machine.  So I am struggling to see the issue being array dimensioning.  I know I can do better with dimensioning of arrays and what I do is not elegant or good practice, but it has always worked in the past.

I understand its only a snippet of code and hard for anyone to spot any issue on this alone.  The overall code is maybe a bit large to include here but maybe I can get it cut down to the basics that are fundamental to this problem, though I was just wondering if there was a reason the for loop was jumping out part way through because of some known daft thing I wasn't aware of.

Thanks again for the comments, I will look into it further and see what happens. 

 

ranny

  • New Member
  • *
  • Posts: 39
Re: For loop jumps about, data is corrupted...
« Reply #6 on: August 14, 2019, 11:28:01 am »
Fixed, to some extent!

The procedure had "n" as a parameter but "n" was also a global array.  When I changed this is worked okay.  However....

Whilst it worked, when debugging the cursor jumps about and the loop variable "i" which should go from 2 to 48 jumps to 30180 or some other strange number.  This does not happen in the original program.

So I dont know why the difference between the two but it works now.  Result is parametric spline as per picture.

Thanks for the support.

Thaddy

  • Hero Member
  • *****
  • Posts: 9278
Re: For loop jumps about, data is corrupted...
« Reply #7 on: August 14, 2019, 12:00:51 pm »
if SizeOf(x) = SizeOf(y) will be always True.

Yes, should be length() instead.
also related to equus asinus.