Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

move, dynamic array, untyped parameter, access violation ?!

218 views
Skip to first unread message

Skybuck Flying

unread,
Dec 1, 2002, 8:40:32 AM12/1/02
to
I was coding some stuff and ran into an access violation.

I managed to re-create the problem and here it is:

It seems using a procedure with a variable untyped parameter and trying to
do a move with a dynamic array leads to access violation.

Why won't this work... ? what's up with move and dynamic arrays ?

// *** begin of test code ***:

procedure test( var something );
var
a : array[0..9] of byte;
begin
a[0] := 10;
a[1] := 20;
a[2] := 30;
a[3] := 40;
a[4] := 50;
a[5] := 60;
a[6] := 70;
a[7] := 80;
a[8] := 90;
a[9] := 100;

move( a, something, 10 );
end;

procedure TForm1.Button1Click(Sender: TObject);
var
b : array[0..9] of byte;
i : integer;

c : array of byte;
begin
{
test( b );

for i:=0 to 9 do
begin
ShowMessage( IntToStr( b[i] ) );
end;
// ok
}
SetLength( c, 10 );

test( c );

for i:=0 to 9 do
begin
ShowMessage( IntToStr( c[i] ) ); // access violation ?!??

end;

c := nil;
end;

// *** end of test code ***:


Skybuck Flying

unread,
Dec 1, 2002, 4:17:14 PM12/1/02
to
Somebody sent me a smart solution.

instead of passing c, just pass first element of c.

so

instead of passing dynamic array, pass first element of dynamic array :)

procedure test( var a );
begin

end;

var
c : array of byte;

begin

SetLength( c, 10 );

test( c[0] ); // this does work :)

c := nil;

end;

"Skybuck Flying" <nos...@hotmail.com> wrote in message
news:asd3g0$r1e$1...@news1.tilbu1.nb.home.nl...

Skybuck Flying

unread,
Dec 1, 2002, 4:23:22 PM12/1/02
to
Interestingly enough this works as well:

pointer(c)^

The delphi doc however says not to do this :)

'Don't dereference dynamic array's' :)

Dynamic arrays are probably more than just pointers...

They probably have some reference counting which is before or behind the
pointer itself :)

"Skybuck Flying" <nos...@hotmail.com> wrote in message

news:asdu89$q8m$1...@news2.tilbu1.nb.home.nl...

Maynard Philbrook

unread,
Dec 1, 2002, 6:52:46 PM12/1/02
to
you must remember that when ever you use the VAR in the parameter, you are
getting a reference to the
object! meaning a pointer address value..
so a dynamic array is a pointer, but since you did not specify the type and
used a VAR, it simple passed
the procedure the address to the Pointer it self.
you use of the Pointer(C)^ is merly getting the contents of C which is a
memory address...

Skybuck Flying

unread,
Dec 2, 2002, 7:12:35 AM12/2/02
to

"Maynard Philbrook" <jam...@mindspring.com> wrote in message
news:3DEAA4BF...@mindspring.com...

> you must remember that when ever you use the VAR in the parameter, you
are
> getting a reference to the
> object! meaning a pointer address value..
> so a dynamic array is a pointer, but since you did not specify the type
and
> used a VAR, it simple passed
> the procedure the address to the Pointer it self.

No that's not true.

The C pointer is de-referenced with the ^ sign.

Pointer(c)^ points to the array itself.

> you use of the Pointer(C)^ is merly getting the contents of C which is a
> memory address...

Yes, the memory address is the address of the array itself.

This address is passed to the var parameter.

So what I am doing is passing the array itself.

Maynard Philbrook

unread,
Dec 2, 2002, 10:30:43 AM12/2/02
to
I really hate to burst ur bubble
but the compiler somply uses the POINTER of the Param C which was be pushed on
the stack as a
ADdress value to the orginal Pointer.
the compiler already knows this, the code generated in the background hides
this from you.
what your doing is more of an indirect access..
meaning that if you were to change the value of C it would screw up the
original pointer reference.
VAR is always passes via ref. meaning that it simply provides the address to the
object..
in this case just another pointer to that actuall array it self.
so your pointer(c)^ is doing something like this in the background.
ASm
Mov EAX, Dword Ptr [C]; // Get the contents of the array pointer pointed by C
Mov AX, Byte Ptr [EAX]; // this line depends on what type you use it for at
the time of Point(C)^.
End;
ur thinkink is this.
ASM
Mov EBX, DWord PTr C; // assumes that C points to the same data as the
original Array pointer does.
Mov AX, [EHX];
End;
so what you seeing at the PAS level is not actually happening.
the use of VAR in the parms is a throw off.
simply put, a VAR on any thing is a pointer to the original object, in this
case its a pointer to the Pointer that points to the array data.
the Pascal code simply hides that fact and lets you use it transparently as if
the pointer it self was pushed on the stack..
why do this ?, what if you wanted to modify the original pointer and not the
data that it points to ?

Skybuck Flying

unread,
Dec 2, 2002, 11:59:09 AM12/2/02
to

"Maynard Philbrook" <jam...@mindspring.com> wrote in message
news:3DEB809A...@mindspring.com...

Try this code:

ShowMessage('address of c^: ' + IntToStr(longint(c)) );

This shows where C points to.

ShowMessage('address of something: ' + IntToStr(longint(@something)) ); //
(inside test procedure)

This shows the address of something.

Which is clearly the same.

I am guessing var is just a temporarely variable on the stack which is
infact a pointer to the data.

Sometimes it's just a pointer to an integer or something else.

In this case it's just a pointer to the data of the array :)

I don't understand the assembler parts... :)

0 new messages