Recent

Author Topic: Error 204 or Invalid Pointer when using SetLength to 0 on a Dynamic Array  (Read 4320 times)

MaxM74

  • New Member
  • *
  • Posts: 17
FPC is 3.3.1

i have a dynamic array of this type

Code: Pascal  [Select][+][-]
  1. type
  2. TMyInfo = record
  3.     Name: String;
  4.     Inst: IMyInterface; //Impemented with a TNoRefCountObject descendent class
  5.   end;
  6.  
  7. var rList: array of TMyInfo;
  8.  

while destroying the application form i do this:

Code: Pascal  [Select][+][-]
  1. var
  2.    i:Integer;
  3.  
  4. begin
  5.   for i:=0 to Length(rList)-1 do
  6.   begin
  7.     try
  8.        if Assigned(rList[i].Inst)  then rList[i].Inst.DoSomething;
  9.     except
  10.     end;
  11.   end;
  12.  
  13.    SetLength(rList, 0); //EXCEPTION Invalid Pointer Operation HERE
  14. end;
  15.  

If i change the code in this way i have no exception:

Code: Pascal  [Select][+][-]
  1. var
  2.    i:Integer;
  3.  
  4. begin
  5.   for i:=0 to Length(rList)-1 do
  6.   begin
  7.     try
  8.        if Assigned(rList[i].Inst)  then rList[i].Inst.DoSomething;
  9.  
  10.        rList[i].Name:='';
  11.        FillChar(rList[i], SizeOf(rList[i]), 0);
  12.     except
  13.     end;
  14.   end;
  15.  
  16.    SetLength(rList, 0); //NO EXCEPTION
  17. end;
  18.  
  19.  

Can anyone explain to me why?
I have to think that SetLength tries to free "the contents of the record" by calling what?
« Last Edit: June 19, 2024, 08:18:08 am by MaxM74 »

AlexTP

  • Hero Member
  • *****
  • Posts: 2479
    • UVviewsoft
Please use forum CODE tag for code blocks.
And... can you give the complete minimal example program?
« Last Edit: June 18, 2024, 01:53:59 pm by AlexTP »

rvk

  • Hero Member
  • *****
  • Posts: 6572
Code: [Select]
   SetLength(rTakersList, 0); //EXCEPTION Invalid Pointer Operation HERE
I agree with the code tags. This is unreadable.

But I see you do SetLength on rTakenList. What is rTakenList? You itterate through rList. Did you mean to do SetLength(rList, 0) ???

Bart

  • Hero Member
  • *****
  • Posts: 5465
    • Bart en Mariska's Webstek
In essence there is no need to free the memory of the dynamic array when your program ends.
(It may be good practice though).
Instead of using SetLength(SomeArry, 0) you can use SomeArray := nil, saves you typing ;-)

Bart

cdbc

  • Hero Member
  • *****
  • Posts: 1645
    • http://www.cdbc.dk
Hi
Code: Pascal  [Select][+][-]
  1. rList[i].inst
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

MarkMLl

  • Hero Member
  • *****
  • Posts: 8007
I agree that OP deserves criticism for not using code tags: there's even a button for it on the standard forum UI. /Particularly/ in the case of somebody less experienced, there is absolutely no excuse for him to go back and read his message after posting it, and it should be immediately apparent that the example's been agrbled by the markup.

However the thing that stands out, in the code that is supposedly working, is this:

Code: Pascal  [Select][+][-]
  1. FillChar(rTakersList, SizeOf(rTakersList), 0);
  2.  

/What/ is rTakersList? If it is either something like a TList or is itself a dynamic array this is a recipe for disaster since it's attempting to zero an opaque access structure, not a data space.

MarkMLl
« Last Edit: June 18, 2024, 10:23:38 pm by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Zvoni

  • Hero Member
  • *****
  • Posts: 2737
Agree with cdbc: I'm more surprised this compiles.....
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

MarkMLl

  • Hero Member
  • *****
  • Posts: 8007
We need somebody to render Joanna into an LLM, that can reject postings with apparent Pascal in the body :-)

Actually, there's probably some very simple tests that could be used, e.g. the appearance of .[ in what should be undecorated English.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 16147
  • Censorship about opinions does not belong here.
Code: Pascal  [Select][+][-]
  1.     try
  2.        if Assigned(rList.Inst)  then rList.Inst.DoSomething;
  3.     except
  4.     end;
Really????
Better write it like this:
Code: Pascal  [Select][+][-]
  1.     try
  2.        if Assigned(rList.Inst)  then rList.Inst.DoSomething;
  3.     except
  4.       // I just shot myself
  5.     end;

This usually happens when a noob has already had exceptions which he or she deemed nonsense and so "protected" the code in the wrong place and in the wrong way.
Now Suicide Sue has likely hidden the real error and can not debug it because there is no valid stackframe.... >:D

(That's twice I mentioned this today , but Eugene promissed he did not use that and he is not a noob)
The problem with this code is that assigned() can fail: not everything that passes assigned is really assigned. It just means the pointer is not nil.
That pointer can be invalid:use after free.
In this case it is even more suicidal because Assigned is already a protection test. If assigned fails or causes an error, you need to find out why. Not eat it with an empty exception.
Also do not mention FreeAndNil, plz. in this context. It just demonstrates why it is bad.

The real problem is the interface in the record: that is always assigned, but the class that supports that interface can be gone to heaven. Store the class reference, not the interface.
« Last Edit: June 18, 2024, 07:01:04 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8007
This usually happens when a noob has already had exceptions which he or she deemed nonsense and so "protected" the code in the wrong place and in the wrong way.
Now Suicide Sue has likely hidden the real error and can not debug it because there is no valid stackframe.... >:D

Give him a break Thaddy. We're all piling on fairly hard because of the lack of code tags and the incomplete example, and when we see what he was actually trying to do things might make sense.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 16147
  • Censorship about opinions does not belong here.
Mark, I merely pointed out where the error came from. Use after free.
If I smell bad code it usually is bad code and that includes my own code.

rvk

  • Hero Member
  • *****
  • Posts: 6572
Mark, I merely pointed out where the error came from. Use after free.
You mean could come from.

(Or do you have that magic ball I lost  ;) )

Besides... we have no idea what rTakersList is and where it comes from (the line that produces the error).

Thaddy

  • Hero Member
  • *****
  • Posts: 16147
  • Censorship about opinions does not belong here.
Well, look at the record? No christal ball necessary.
If I smell bad code it usually is bad code and that includes my own code.

rvk

  • Hero Member
  • *****
  • Posts: 6572
Well, look at the record? No christal ball necessary.
The record in tList has nothing to do with freeing rTakersList, of which we know nothing about.

So yeah, I find it really amazing you can find fault in this non compilable code, which errors on a line which has nothing to do with interfaces.

cdbc

  • Hero Member
  • *****
  • Posts: 1645
    • http://www.cdbc.dk
Hi
The only list thingy I can find declared is:
Code: Pascal  [Select][+][-]
  1. var rList: array of TMyInfo;
'rTakersList' is nowhere declared, but funnily enough, worked on and setlength'ed  :D %) :P
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

 

TinyPortal © 2005-2018