Link to home
Start Free TrialLog in
Avatar of oalawna
oalawna

asked on

access violation error

Hi, anybody have an idea why the marked line in this function might be raising an access violation error? It raises the exception affter being called several times.
type
  TMyArray = array of integer;

procedure ReduceArrayByNO(var Ar: TMyArray; NO: integer);
var
  I, J, X, N: Integer;
  Len: Integer;
  CopyAr: TMyArray;
begin
  try
    Len := high(Ar) - low(Ar);
    N := Len - 1; //4
    SetLength(CopyAr, Len);// the copy array's length is now less than the original's by one
    J := 0;
    X := 0;
    for I := 0 to Len do
      begin
        if Ar[I] <> NO then
          begin
            CopyAr[X] := Ar[J];**************************************
            J := J + 1;
            X := X + 1;
          end;
        if Ar[I] = NO then
          begin
            J := J + 1;
          end;
      end;
    SetLength(Ar, Len);
    for I := 0 to N do
      begin
        Ar[I] := CopyAr[I];
      end; // for
  finally
    SetLength(CopyAr, 0);
  end;
end;

thanks
SOLUTION
Avatar of mokule
mokule
Flag of Poland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of oalawna
oalawna

ASKER

why? I dont think so becuase len:=high(ar)-low(ar);//if ar is [0,1,2,3,4,5] len is 5 and
I want actually to loop through all elements of this array from 0 to 5.
SetLength(CopyAr, Len);// the copy array's length is now less than the original's by one

Shouldn't that be

SetLength(CopyAr, N);// the copy array's length is now less than the original's by one
Is this what you're trying to do?

procedure ReduceArrayByNO(var Ar: TMyArray; NO: integer);
var
  I: Integer;
begin
  try
    for I := NO to Length(Ar) - 2 do
      Ar[I] := Ar[I + 1];

    SetLength(Ar, Length(Ar) - 1);
  except
  end;
end;
Avatar of oalawna

ASKER

Paul thank, but actually i simplified the function to ask here. the function will take an array of cards and the card you want to exclude from the array. I approched this by first creating a copyarray whose length is less than the original by one. Then while filling the copyarray with items in the original, i put a condition that if the NO provided which is a card or a number in this example is equal to Ar[I] then ignore it and continue until finished. this way i am assured that we will not be outbounds. here is the code again with comments

type
  TMyArray = array of integer;

procedure ReduceArrayByNO(var Ar: TMyArray; NO: integer);//suppose Ar has 6 elements
var
  I, J, X, N: Integer;
  Len: Integer;
  CopyAr: TMyArray;//now this will hold 5 elements
begin
  try
    Len := high(Ar) - low(Ar);//this will be 5-0=5
    N := Len - 1;    //N=5-1=4
    SetLength(CopyAr, Len);// Len is 5 (5 elements)
    J := 0;
    X := 0;
    for I := 0 to Len do //0 to 5 that is looping through 6 elements of the original array
      begin
        if Ar[I] <> NO then //we will copy the elemnts of original Array to the copy array only if NO is excluded
          begin
            CopyAr[X] := Ar[J];**************************************
            J := J + 1;
            X := X + 1;
          end;
        if Ar[I] = NO then
          begin
            J := J + 1;
          end;
      end;
    SetLength(Ar, Len);//now we reset the original array which had 6 element to accept only 5 elements. Len is 5
    for I := 0 to N do //N for i=0 to 4 because we loop through 5 elements of the new original array and the copyarray
                             //both arrays hold 5 elements
      begin
        Ar[I] := CopyAr[I];
      end; // for
  finally
    SetLength(CopyAr, 0);
  end;
end;


thanks
Avatar of oalawna

ASKER

http://www.geocities.com/oalawneh/ToSend.zip

the function is working fine and above is an example project.
I dont know what might be producing the access violation error as I could not reproduce the error while tracing with same parameters.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of oalawna

ASKER

Ok thanks I think it something wrong with delphi environement.

Hi

Your problem is probably the declaration

I:Integer;


This is a very usualy declaration especially amongst people used to Visual Basic.

Likewise

x:Integer;

This is caused by I or X being globally delared within another unit (perhaps a VCL).

Due to bad memory management by Delphi this causes the problem you are seeing.

I had exactly the same problem myself and by simply changing the variable name to ICounter, the problem disappeared.

The long term solution is to use a different memory manager.  I use FastShareMem.pas myself and now have no such problems.  You can download free from http://www.torry.net/pages.php?id=228 .

This is an essential for any project in my opinion.....


But hey .... what do I know.......


Voodooman

Avatar of oalawna

ASKER

thank you voodooman. This solved the problem but why dont we find something official about this topic in delphi help?
confused:)

Hi

well why do Microsoft only have 'features by design' and not bugs.  I remember when Visual Basic support was free getting faxed a 15 page workaround for a bug that they called a 'design feature'.

Borland, Microsoft and all don't admit to these things.

This took me all the day to figure out.  I work for myself so this was a day that I didn't get paid for.

I include FastShareMem in all my projects and have no problem since.

Don't forget to allocate the points......

Voodooman