[Delphi]TObjectList.Clear() geeft Access Violation

Pagina: 1
Acties:
  • 152 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Hmm, 'k heb een vreemd probleem waar ik kop noch staart aan krijg... :(

Ik heb 2 Delphi Forms, een overzichtscherm, en een scherm waar ik filtercriteria kan opgeven.

Het scherm met de filtercriteria kan ik openen vanop het lijstscherm, en, aangezien ik bij het openen van m'n filterscherm wil zien wat de vorige filtercriteria waren, bewaar ik die filtercriteria in m'n overzichtsscherm.

Op m'n overzichtsscherm, en op m'n filterscherm heb ik een TObjectList staan.

Als ik m'n filterscherm open, dan wordt er een TObjectList gecreeërd:
code:
1
FilterId := TObjectList.Create();

Ik stel filtercriteria in, en pas m'n filter toe. Dit gaat goed, ik krijg enkel items op m'n overzichtsscherm te zien die aan m'n filtercriteria voldoen.

Later open ik m'n filterscherm opnieuw, en dit gaat ook goed. M'n filtercriteria die ik had ingesteld worden mooi getoond.

Het probleem komt nu;
Ik verander m'n filter-criteria en wil die nieuwe filter toepassen. Om dat goed te laten verlopen, wil ik m'n TObjectList leegmaken, en dat doe ik met volgende code:
code:
1
FilterId.Clear();

Nu krijg ik daarop een Access Violation, terwijl hij die code ook uitvoert als ik m'n filter voor de eerste keer uitvoer en het dan perfect werkt.
Ik ben zeker dat die TObjectList gealloceerd is, want, bij het inladen van m'n filterscherm, overloop ik datzelfde TObjectList object om m'n vorige criteria te tonen en toen zaten er zeker objecten in.

Ook als ik volgende code errond zet:
code:
1
2
3
if Assigned(FilterId) then begin
  FilterId.Clear();
end;

dan wordt die clear() uitgevoerd, dus moet die TObjectList wel gealloceerd zijn.

* whoami snapt het nu niet...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Blijkt dat die TObjectList leeg is als ik die Clear wil doen, terwijl die niet leeg is als ik m'n filterform inlaadt.
Tussen die 2 stappen zit er nergens code die m'n List gaat leegmaken... :?
* whoami snapt het helemaal niet meer.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06 16:43

Varienaja

Wie dit leest is gek.

Op vrijdag 12 juli 2002 15:58 schreef whoami het volgende:
Blijkt dat die TObjectList leeg is als ik die Clear wil doen, terwijl die niet leeg is als ik m'n filterform inlaadt.
Tussen die 2 stappen zit er nergens code die m'n List gaat leegmaken... :?
* whoami snapt het helemaal niet meer.
Het Clearen van een lege lijst mag natuurlijk zowiezo geen Acces Violation opleveren.

Je hebt toch FilterID niet als deel van je filter-schermpje he? Want dan krijg je inderdaad (vaak) hetzelfde terug als je een scherm opnieuw opent, en ellende wanneer je een ander scherm opent.

* Varienaja heeft ooit heel lang gezocht waarom onderstaand stukje *soms* fout ging:
code:
1
2
3
4
Spelletje.Create;
Spelletje.VoerUit;
Spelletje.Free;
Highscores.Add(Spelletje.Score);

Als dat het niet is, kan het handig zijn als je een watch zet op FilterID. Vervolgens step je dan door een enorm eind code, om te kijken op welk punt het ding opeens niet meer gedefinieerd is, waardoor je later die A.C. krijgt.

Siditamentis astuentis pactum.


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Op vrijdag 12 juli 2002 16:08 schreef Varienaja het volgende:

[..]

Het Clearen van een lege lijst mag natuurlijk zowiezo geen Acces Violation opleveren.
Inderdaad.
Je hebt toch FilterID niet als deel van je filter-schermpje he? Want dan krijg je inderdaad (vaak) hetzelfde terug als je een scherm opnieuw opent, en ellende wanneer je een ander scherm opent.
Toch wel, maar iedere keer ik een scherm maak, wordt die TObjectList gecreeërd en opgevuld. En daar gaat alles goed.
Ze wordt pas Gefree-ed bij het afsluiten van het scherm. (En ook dat loopt mis), ook daar krijg ik Access Violations.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Anoniem: 41032

welke Access Violation krijg je?
edit:

ik bedoel, welk adres? 0000000 of iets anders?

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Op vrijdag 12 juli 2002 16:13 schreef FireWizz het volgende:
welke Access Violation krijg je?
Project ... raised exception class 'EAccessViolation with message 'Access Violation at address 40003AB0 in module 'Vcl50.bpl'. Read off address 00000001'.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Anoniem: 41032

hm, 0000001 lijkt op een nil pointer. krijg je ook een AV als je het standalone draait (dus <applicatie>.exe) en niet vanuit delphi?

Acties:
  • 0 Henk 'm!

  • Aetje
  • Registratie: September 2001
  • Laatst online: 24-03-2023

Aetje

Troubleshooting met HAMERRR

Klinkt alsof je met die clear een niet bestaande lijst probeert te wipen. Probeer er een .add('moo'); voor te zetten, dan weet je dat de list bestaat...

Forget your fears...
...and want to know more...


Acties:
  • 0 Henk 'm!

Anoniem: 41032

het is in ieder geval belangrijk om te weten waar FilterId gedeclareerd is. Is dit binnen het TForm object, of gewoon globaal binnen de Filter unit?

dus waar staat
code:
1
 FilterId : TObjectList;

Acties:
  • 0 Henk 'm!

  • Aetje
  • Registratie: September 2001
  • Laatst online: 24-03-2023

Aetje

Troubleshooting met HAMERRR

Uit de Deplhi hulp:
procedure Clear; virtual;

Virtual methods employ a more complicated, and more flexible, dispatch mechanism than static methods. A virtual method can be redefined in descendant classes, but still be called in the ancestor class. The address of a virtual method isnt determined at compile time; instead, the object where the method is defined looks up the address at runtime.
Zo te zien gaat het zoeken naar de pointer naar de procedure niet goed...

Forget your fears...
...and want to know more...


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Op vrijdag 12 juli 2002 16:18 schreef FireWizz het volgende:
hm, 0000001 lijkt op een nil pointer. krijg je ook een AV als je het standalone draait (dus <applicatie>.exe) en niet vanuit delphi?
Ja, dan krijg ik het ook.
Op vrijdag 12 juli 2002 16:23 schreef Aetje het volgende:
Klinkt alsof je met die clear een niet bestaande lijst probeert te wipen. Probeer er een .add('moo'); voor te zetten, dan weet je dat de list bestaat...
Aan een nil-pointer heb ik ook al gedacht, maar het vreemde is gewoon, dat als ik volgende code uitvoer, hij gewoon geen Access Violation geeft:
code:
1
2
// MyObjectList.Clear();
MyObjectList.Add(TObject(AnObject));

Het adden lukt dus gewoon (de List kan dus niet nil zijn), maar het clearen lukt niet.

Ik ga die clear eens weglaten en gewoon door de List wandelen en alle items verwijderen met Delete. Eens zien wat dat geeft.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Anoniem: 41032

zou het dan zo kunnen zijn dat hij een AV krijgt omdat hij een object dat in FilterID hangt probeert te free-en? dus niet FilterID zelf, maar 1 van de filterobjectjes die je hebt toegevoegd?

de clear probeert namelijk alles weer vrij te geven, ook zijn kinderen

Acties:
  • 0 Henk 'm!

  • Aetje
  • Registratie: September 2001
  • Laatst online: 24-03-2023

Aetje

Troubleshooting met HAMERRR

List kan wel nil zijn. Dit doet me denken aan de probs die ik met TStringlist heb gehad. Als ik een directe toekenning probeer met MyStringList[3] := String, krijg ik een AV als de stringlist minder als 4 strings heeft.
Stringlist clearen als ie nog nooit een string had gehad werkte ook niet.

probeer iig de volgende code als testje:
code:
1
2
3
4
5
6
7
8
9
10
11
Procedure TestObjectList;
var MyObjectList: TObjectList; // pointer naar MyObjectList

begin
  MyObjectList := TObjectList.Create(nil);
  try
    MyObjectList.Clear; // Geeft ie een AV?
  finally
    MyObjectList.Free; // ff dealloceren
  end;
end;

Forget your fears...
...and want to know more...


Acties:
  • 0 Henk 'm!

  • Aetje
  • Registratie: September 2001
  • Laatst online: 24-03-2023

Aetje

Troubleshooting met HAMERRR

Op vrijdag 12 juli 2002 16:31 schreef FireWizz het volgende:
zou het dan zo kunnen zijn dat hij een AV krijgt omdat hij een object dat in FilterID hangt probeert te free-en? dus niet FilterID zelf, maar 1 van de filterobjectjes die je hebt toegevoegd?

de clear probeert namelijk alles weer vrij te geven, ook zijn kinderen
Dat kun je instellen:
Allows TObjectList to free objects when they are deleted from the list or the list is destroyed.

property OwnsObjects: Boolean;

Description

OwnsObjects allows TObjectList to control the memory of its objects. If OwnsObjects is True (the default),

calling Delete or Remove frees the deleted object in addition to removing it from the list.
calling Clear frees all the objects in the list in addition to emptying the list.
calling the destructor frees all the objects in the list in addition to destroying the TObjectList itself.
assigning a new value to an index in Items frees the object that previously occupied that position in the list.

Even if OwnsObjects is True, the Extract method can be used to remove objects from the list without freeing them.
Eens op FALSE zetten :?

Forget your fears...
...and want to know more...


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Op vrijdag 12 juli 2002 16:31 schreef FireWizz het volgende:
zou het dan zo kunnen zijn dat hij een AV krijgt omdat hij een object dat in FilterID hangt probeert te free-en? dus niet FilterID zelf, maar 1 van de filterobjectjes die je hebt toegevoegd?
Hmmm, nee. Ik heb hetzelfde probleem als ik er integers aan hang dacht ik.

Als ik er doorwandel en ze wil deleten (met .Delete(Indx)), dan heb ik hetzelfde probleem.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Aetje
  • Registratie: September 2001
  • Laatst online: 24-03-2023

Aetje

Troubleshooting met HAMERRR

Op vrijdag 12 juli 2002 16:27 schreef whoami het volgende:
Aan een nil-pointer heb ik ook al gedacht, maar het vreemde is gewoon, dat als ik volgende code uitvoer, hij gewoon geen Access Violation geeft:
code:
1
2
// MyObjectList.Clear();
MyObjectList.Add(TObject(AnObject));

Het adden lukt dus gewoon (de List kan dus niet nil zijn), maar het clearen lukt niet.
Doe liever eens:
code:
1
2
MyObjectList.Add(TObject(AnObject));
MyObjectList.Clear();

Forget your fears...
...and want to know more...


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Woei.
Ik heb die OwnsObjects op False gezet voor ik m'n list clear en dan werkt het wel!.
Thx!

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Anoniem: 41032

Als ik m'n filterscherm open, dan wordt er een TObjectList gecreeërd:
waarom creeer je FilterID als je het scherm opent? wellicht kun je beter deze aktie 1-mailg in de Form.create uitvoeren, dan werk je altijd met hetzelfde object. Lijkt me zoiezo verstandiger, tenzij je natuurlijk een goede reden hebt.. ;)

edit:
gefeliciteerd!

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Probleem heeft waarschijnlijk te maken dat ik m'n ObjectList ook doorgaf aan een ObjectList in m'n overzichtscherm, en aangezien die objecten ook nog in de List die op m'n overzichtscherm staat hangen kon hij ze niet wissen.
(Tenminste, da's wat ik denk.).

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Op vrijdag 12 juli 2002 16:41 schreef FireWizz het volgende:

[..]

waarom creeer je FilterID als je het scherm opent? wellicht kun je beter deze aktie 1-mailg in de Form.create uitvoeren, dan werk je altijd met hetzelfde object. Lijkt me zoiezo verstandiger, tenzij je natuurlijk een goede reden hebt.. ;)
Staat in m'n form.create hoor.
Als ik m'n filterscherm open, doe ik dat met volgende code:
code:
1
2
3
4
frmFilter := TFilterForm.Create(Self);
frmFilter.DoAfterOk := FiltersDoorgeven;
frmFilter.SetPreviousFilter();
frmFilter.Execute();

DoAfterOk is een TNotifyEvent, die uitgevoerd wordt als ik op OK klik in m'n filterscherm. Daar hang ik dus de procedure 'FiltersDoorgeven' aan, die de ingestelde filters gaat gaan halen van m'n filterscherm.
In m'n Execute functie ga ik m'n filterscherm gaan initialiseren en tonen.
In de Create wordt de TObjectlist gecreeërd.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Anoniem: 41032

wat het ook zou kunnen zijn...
je zegt:
Hmmm, nee. Ik heb hetzelfde probleem als ik er integers aan hang dacht ik.
maar de list kan alleen objecten free-en die daadwerkelijk object zijn...dus geen integers. als je een clear doet met een integer gaat het dus fout, met een object niet.

zie ook de volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
procedure TForm1.BitBtn1Click(Sender: TObject);
var lst : tobjectlist;
    b   : integer;
begin
  lst := tobjectlist.create;
  lst.add(tobject(b));
  lst.clear;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
var lst : tobjectlist;
    c   : tobject;
begin
  lst := tobjectlist.create;
  c := tobject.create;
  lst.add(tobject(c));
  lst.clear;
end;

de tweede gaat goed, de eerste klapt er uit...

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Huh, vreemd, daar heb ik nog geen problemen mee gehad...
Zal het nog rap even testen.

Getest, en idd, hij geeft een Access Violation.
Als ik er dan echter OwnsObjects op False zet, dan werkt het wel.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Anoniem: 41032

misschien dat je dus bij de tweede keer het filterfom openen met een hybride lijst werkt?

dit klopt in ieder geval:
Als ik er dan echter OwnsObjects op False zet, dan werkt het wel.
in ieder geval weer een mysterie opgelost :)

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 18:55
Op vrijdag 12 juli 2002 17:05 schreef FireWizz het volgende:
misschien dat je dus bij de tweede keer het filterfom openen met een hybride lijst werkt?

dit klopt in ieder geval:
[..]

in ieder geval weer een mysterie opgelost :)
Logisch eigenlijk, want dan wordt de Clear() van de objects in die list niet uitgevoerd, en aangezien Integers geen Clear hebben...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Je probleem kan op manieren veroorzaakt worden:

* Doordat je de objectenlijst doorgeeft aan een andere lijst, die ook ownsobjects is, en die eerder wordt gefreed of gecleared/delete dan de oorspronkelijke lijst.

* Doordat je onderliggende objecten freed die in een ownsobjects lijst zitten en die dus naderhand nog een keer gefreed proberen te worden (av).

* Doordat je met nil of met rare pointer adressen aan het vogelen bent. >:)

Let op! Ownsobjects overal op false zetten lost wel de AV op, maar creeërt wel een potentieel geheugenlek. Ik zou als ik jou was wel even kijken waar de elementen uit jouw objectenlijst nu dan worden gefreed, ipv in de lijst.

Het is vaak makkelijker om één lijst in je programma te houden, en in de verschillende forms een referentie naar die lijst te houden, ipv de lijst kopiëren, en ownsobjects te gebruiken voor geheugenbeheer

Acties:
  • 0 Henk 'm!

  • Aetje
  • Registratie: September 2001
  • Laatst online: 24-03-2023

Aetje

Troubleshooting met HAMERRR

Op vrijdag 12 juli 2002 17:24 schreef misfire het volgende:* Doordat je onderliggende objecten freed die in een ownsobjects lijst zitten en die dus naderhand nog een keer gefreed proberen te worden (av).
Object dat al niet meer bestaat freeen geeft geen AV.
Object dat niet meer bestaat destroyen geeft WEL een AV.

Forget your fears...
...and want to know more...


Acties:
  • 0 Henk 'm!

  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 23:26

Delphi32

Heading for the gates of Eden

Op zaterdag 13 juli 2002 12:40 schreef Aetje het volgende:
Object dat al niet meer bestaat freeen geeft geen AV.
Object dat niet meer bestaat destroyen geeft WEL een AV.
Probeer dan eens het volgende:
code:
1
2
3
4
5
6
procedure TForm1.Button1Click(Sender: TObject);
var
  MyButton: TButton;
begin
  MyButton.Free;
end;

Geen AV, daarin heb je gelijk... maar op W98, W95 en vast ook ME, krijg je hele rare resultaten >:)
Pagina: 1