Solved

# access violation error

Posted on 2005-04-30
267 Views
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
0
Question by:oalawna

LVL 17

Assisted Solution

for I := 0 to Len do
shouldn't it be
for I := 0 to Len-1 do

0

Author Comment

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.
0

LVL 5

Expert Comment

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
0

LVL 5

Expert Comment

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;
0

Author Comment

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
0

Author Comment

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.
0

LVL 5

Accepted Solution

I cannot find any problems in the project above... It works fine for me
0

Author Comment

Ok thanks I think it something wrong with delphi environement.
0

LVL 5

Expert Comment

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

0

Author Comment

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

LVL 5

Expert Comment

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
0