Recent

Author Topic: Lack of continuity when copying arrays?  (Read 7192 times)

morgoe

  • Newbie
  • Posts: 3
Lack of continuity when copying arrays?
« on: July 31, 2010, 06:53:49 am »
I've programmed a bit in Java in the past, but I'm now trying to learn Pascal. I'm getting a really weird issue though, maybe you guys can help. Here's my code (well, the problem bits anyway).

Code: [Select]
program Test;

var
    myArray: array[1..200] of integer;
    i: integer;

Procedure Test (Input: Array Of Integer);
begin
     writeln('200th Entity is: ', Input[200]);
     writeln('200th Entity is: ', myArray[200]);
end;

begin
    for i:=1 to 9 do
        myArray[i] := 10 + i;
    test(myArray);
    readln;
end.    

The array of integers, 'myArray', is being inserted into the procedure 'Test', and no modifications are done, I'm simply reading the final integer in the array. Except the output is this:

200th Entity is: -6108936
200th Entity is: 0.

The second entry is the original array, the first is the copied one. Why are they different? It SHOULD be 0 in both. There are no problems for ANY other entries, if I do entry 199, both are 0. If I do 5, both are 15. If I do entry 200, one is 0 and one is some huge number (this number has varied through my various tests, can be +ve or -ve, once it was as low as 20, but its not random, every time I run the number is the same. But changing the code does affect this number.
« Last Edit: July 31, 2010, 11:14:44 am by morgoe »

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3538
Re: Lack of continuity when copying arrays?
« Reply #1 on: July 31, 2010, 08:08:26 am »
The array of integers, 'myArray', is being inserted into the procedure 'Test', and no modifications are done, I'm simply reading the final integer in the array.

Dynamic Arrays are have zero-based index, so I guess that your original array [1..200] is converted into an array [0..199] when converted to a dynamic array.

Then while accessing the position 200 (or 3000 in your code), you are reading out-of-bounds, that's it, you are reading a random memory area. The correct reading of the last position of the array would be:

     writeln('Last Entity is: ', Input[Length(Input)-1]);

or

     writeln('200th Entity is: ', Input[199]);


I don't know if your array is being copied or passed as a pointer, but if you want to make sure it isn't copied, but rather passed as a pointer, then declare the input as "var" type:

Procedure Test (var Input: Array Of Integer);

But then the compiler will expect the types to match exactly and you won't be able to pass a static array to a dynamic array parameter, you will have to make your variable dynamic and initialize it.


var
  myArray: array of integer;

begin
  SetLength(myArray, 200); // now it goes from 0 to 199
   ....

morgoe

  • Newbie
  • Posts: 3
Re: Lack of continuity when copying arrays?
« Reply #2 on: July 31, 2010, 10:12:33 am »
Yes, that's what its doing. It's basically moving everything in the array one place to the 'left'. So if I ask for
Input[4]
and
myArray[4],

I'll actually get the results of
myArray[5]
and
myArray[4]


How can I avoid this? Is there some syntax to make my original array a dynamic array?

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4570
  • I like bugs.
Re: Lack of continuity when copying arrays?
« Reply #3 on: July 31, 2010, 10:27:37 am »
Code: [Select]
Procedure Test (Input: Array Of Integer);
The parameter looks like a dynamic array but it is not. It is called "open array parameter" or something. You should not use it here.
Instead you should define an own type a use it as function parameter.

Code: [Select]
type
 TMyArray = array[1..200] of integer;

var
 myArray: TMyArray;
...
Procedure Test (Input: TMyArray);

Your original code is confusing. It defines 1..200, initializes 1..9 and accesses at 3000.

Juha
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

morgoe

  • Newbie
  • Posts: 3
Re: Lack of continuity when copying arrays?
« Reply #4 on: July 31, 2010, 11:17:34 am »
Code: [Select]
Procedure Test (Input: Array Of Integer);
The parameter looks like a dynamic array but it is not. It is called "open array parameter" or something. You should not use it here.
Instead you should define an own type a use it as function parameter.

Ok, thanks. That wasn't my code, I was modifying someone else's.

Code: [Select]
type
 TMyArray = array[1..200] of integer;

var
 myArray: TMyArray;
...
Procedure Test (Input: TMyArray);

Your original code is confusing. It defines 1..200, initializes 1..9 and accesses at 3000.

Juha

My mistake about the accessing at 3000, that's been fixed. I think I was testing something and forgot to change it back. The reason it doesn't initialize all 200 is because I wanted to be able to work out when the last entry in the array was, not when it ended. That bit is also not my code.

Troodon

  • Sr. Member
  • ****
  • Posts: 484
Re: Lack of continuity when copying arrays?
« Reply #5 on: July 31, 2010, 05:36:55 pm »
These are different types in Object Pascal:

array [1..200] of integer
array of integer

Besides, when passed to subroutines/functions as parameters, dynamic arrays become open arrays, which is consistent with both explanations above.
« Last Edit: July 31, 2010, 05:42:53 pm by Troodon »
Lazarus/FPC on Linux

 

TinyPortal © 2005-2018