0

I'd like to know if anyone could point me out to what would be the difference when using the two different copy approaches for array, which is defined as type.

I needed to make a function that would order the elements of integers in dynamic array, from either min to max or max to min. Therefore, I created a new type like this:

type IntArray = array of integer;

Then I defined a function to sort, with two directions, which are identified by integer passed, with parameter being 0 to sort towards minimum (max -> min) or 1 to sort towards max (min -> max).

function SortArray(ToSort: IntArray; Direction: integer): IntArray;
var count, i: integer;
Label Label1, Label2;
begin
count:=Length(ToSort);
if (Direction = 1) then
  begin
    Label1:
    for i := 0 to count-2 do
      begin
        if ToSort[i+1] > ToSort[i] then
          begin
            ToSort[i+1]  :=ToSort[i]   +ToSort[i+1];
            ToSort[i]    :=ToSort[i+1] -ToSort[i];
            ToSort[i+1]  :=ToSort[i+1] -ToSort[i];
            GoTo Label1;
          end;
      end;
  end
else
if (Direction = 0) then
  begin
    Label2:
    for i := 0 to count-2 do
      begin
        if ToSort[i+1] < ToSort[i] then
          begin
            ToSort[i+1]  :=ToSort[i]   +ToSort[i+1];
            ToSort[i]    :=ToSort[i+1] -ToSort[i];
            ToSort[i+1]  :=ToSort[i+1] -ToSort[i];
            GoTo Label2;
          end;
      end;
  end;

Result:=ToSort;

Now, this function works fine as it seems, however the result differs regarding how I define the arrays that are passed to the function call;

I have an OnClick event for a button, which gives two calls of the function:

procedure Button1Click(Sender: TObject);
var a, b: IntArray;
  i: Integer;
begin
SetLength(a, 10);
SetLength(b, 10);

for i := 0 to 9 do
  begin
    a[i]:=Random(100);      
    b[i]:=a[i];             // Example 1;
  end;

// b:=a;                    // Example 2;

a:=SortArray(a, 1);
b:=SortArray(b, 0);

for i := 0 to 9 do
  begin
    Listbox1.Items.Add(InttoStr(a[i]));
    Listbox2.Items.Add(InttoStr(b[i]));
  end;
end;

Now the thing is, if I define array B the way it is provided with example 1, -> the function works fine. A is sorted towards maximum, while B is sorted towards minimum;

However, if I define array B the way it is provided with example 2, -> the function gives me the same result for both calls, both being arrays sorted towards maximum (as called in the first call).

Why does it make a difference how I define array b, and why shouldn't I copy it directly as var to var? Doesn't seem to make much sense to me at this point...

10
  • 1
    This is explained in the documentation docwiki.embarcadero.com/RADStudio/en/… Start reading "if X and Y ..." Commented Dec 7, 2014 at 23:49
  • 1
    If what you have is a pointer then the assignment copies the reference. For instance an assignment wouldn't copy a class instance. Strings are the exceptions. Commented Dec 8, 2014 at 0:11
  • 1
    Strings have copy-on-write (COW) mechanism, so they are different from other reference types. Commented Dec 8, 2014 at 0:16
  • 1
    Lots of problems with the code though. Needless duplication. You can do both increasing and decreasing in the same code but switched just on the compare. You need to learn about Boolean. Your swap technique is opaque and obscure. Use a temp. Goto is needless and to be avoided. You sort is an inefficient bubble sort type. TArray<Integer> is the dyn array of integer. Also, delphi already comes with sorting functions. Commented Dec 8, 2014 at 7:12
  • 1
    So, here's your sort function: docwiki.embarcadero.com/Libraries/en/… Commented Dec 8, 2014 at 7:44

1 Answer 1

3

In example 1, you're looping through and assigning the value of each element in a to the corresponding slot in b. You have two separate arrays, with totally separate content.

b[i] := a[i];

So sorting works on each independent array, and things work as you intend. You can verify this by setting them to different values and then inspecting the elements to confirm they're in fact different:

a[0] := 1;
b[i] := 2;   // Inspecting shows a[0] <> b[0].

In example 2, you're setting b to point to a, which means that accessing b[1] is actually accessing the same memory location as a[1]. You only have one array (a), with two references to it (a and b). Sorting is actually working on a single array, so all you're doing is first sorting the array in ascending order and then resorting the same array (through the second reference) in descending order, and you don't get the results you expect.

You can confirm this by again setting them to different values and then inspecting the elements, but this time they'll be the same value:

b := a;
a[0] := 1;
b[0] := 2;      // Both a[0] and b[0] now contain the value 2.
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.