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

Somehow TrySetLength is causing ACCESS VIOLATIONS ?! WHY ?!

10 views
Skip to first unread message

Skybuck Flying

unread,
Aug 29, 2022, 2:51:46 AM8/29/22
to
See comments at updated comment section.

unit Unit_TrySetLength_version_003;

{

TrySetLength

version 0.01 created on 5 juli 2006 by Harald Houppermans.

Usage of TrySetLength routine:

Typecast any array to a Tarray type so that it can be passed to
the TrySetLength function. For now the TrySetLength function can only be used
to specify a single dimension. Multi dimension length specifiers not supported.

}

{

version 0.02 created on 5 juli 2006 by Harald Houppermans.

+ Conditional inline directive added (INLINE_ON)

}

{

version 0.03 created on 5 juli 2006 by Harald Houppermans.

- inline removed

}

{

version 0.03 updated comments on 29 august 2022 by Harald Houppermans.

SOMEHOW THIS CODE IS:

1. BOMBING IN DELPHI 10.3

2. IT ESPECIALLY BOMBS FOR DYNAMIC ARRAYS OF NON-CLASS TYPES, FOR EXAMPLE
RECORDS ?!? ARRAY OF RECORDS ?! WHY AND WTF ?!

MAYBE THIS CODE WAS ONLY MENT TO WORK WITH CLASSES ?!?! WHY IT DON'T WORK
WITH OTHER STUFF ?! BEWARE !?!?!?!?!

THIS PRODUCED ACCESS VIOLATION:

USING IT REQUIRES A TYPE TO TARRAY WHICH IS ARRAY OF TvarRec

TrySetLength( TArray(YourDynamicArrayOfSomeType), 1000 );

Maybe this type casting is causing some kind of issue ?

Maybe something changes internally because of generics ? or they not
included ?! NO IDEA.

Maybe it cannot handle records which contain arrays of records ? or
static arrays or something ?! It's WEIRD ?!

}

interface

type
Tarray = array of TvarRec;

function TrySetLength( var ParaVar : Tarray; const ParaNewLength : integer ) : boolean;

implementation

function TrySetLength( var ParaVar : Tarray; const ParaNewLength : integer ) : boolean;
begin
try
SetLength( ParaVar, ParaNewLength );
result := true;
except
result := false;
end;
end;

end.

Bye,
Skybuck.

Skybuck Flying

unread,
Sep 10, 2022, 10:30:58 PM9/10/22
to
Calling TrySetLength on dynamic array of records causes memory corruption on some cases. It seems the array of records is not cleared properly.

Hard to detect, the memory manager available memory should be set to garbage, to prove it ? How to do this ?

I suspect the problem is with open array parameters which are written internally as array of TvarRec, TvarRec does not have a vtRecord... and perhaps the clear routine miss-understands the size of the record and/or array and does not clear it properly.

Bye,
Skybuck.

Skybuck Flying

unread,
Jan 13, 2023, 11:47:46 AM1/13/23
to
The problem was TvarRec, SetLength is using it as the size of the elements leading to "ElementCount * SizeOf(TvarRec));

TVarRec is size of 8 bytes. Basically this explains why array of classes would work and array of records would not work if the record was larger than 8 bytes.

A class is a pointer of 4 bytes, or 8 bytes in 64 bit mode ! LOL, so it happened to fit.

Anyway solving this problem is beyond the scope of this quick posting, but I did manage to write some better TrySetLength functions but it is a very large topic.

Some ideas include DynArraySetLength or using Generic Methods or Generic classes and open array parameters or array parameters to mimic "the compiler magic" that is involved with SetLength.

Check skybuck2000 youtube account to find these videos.

One video is here, but there are others:

I spent a whole day on this, so can't sum it up in a single posting lol, then again maybe, but not gonna do it:

It will group these 3 videos under the term: (Fri13th Part x of 3) to give some order to these video, and it's kinda funny cause it's Friday the 13th of january 2023 ! ;)

(Fri13Th Part 1 of 3) Delphi: Exploring the mysterious SetLength function and maybe TrySetLength problems...
https://youtu.be/rraFJfMtWXM

(Fri13Th Part 2 of 3) Delphi: Does dynarraydim exist ?
https://youtu.be/9WlIZfRPD9Q

(Fri13Th Part 3 of 3) Delphi: TrySetLength continued, DynArrayDim does exist ! =D
https://youtu.be/5MxN_GzZV_A

One more thing, this posting is related to it, and contains some more information/context about the problem/solution:

Delphi 10.3 run button leads to strange compile/build failure:
https://groups.google.com/g/alt.comp.lang.borland-delphi/c/7UpulvwsKAE

I also have some backwards compatible solution, but it requires passing the TypeInfo(TSomething), DimensionCount, [Size1,Size2,Size3] parameters.

Bye for now,
Skybuck.
0 new messages