[Delphi] Vastloper op een exit commando

Pagina: 1
Acties:

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Binnen een bepaalde procedure heb ik het volgende staan:

Delphi:
1
2
if (high(AG)<0) then
    exit;

Of tewel hij moet de procedure (noem ik ff procedure1) beeindigen zodra de Array AG leeg is. Dat doet ie normaal gesproken goed maar in sommige gevallen niet.

Dan krijg ik de volgdene error:

---------------------------
Debugger Exception Notification
---------------------------
Project ArtikelAanZoneToewijzer.exe raised exception class EInvalidPointer
with message 'Invalid pointer operation'. Process stopped. Use Step or Run
to continue.
---------------------------
OK Help
---------------------------

Dat doet hij dan in het geval als ik heb aangegeven in het programma dat hij na procedure1, procedure2 moet starten.
Maar er wordt altijd begonnen met procedure 1. Echter hij loopt echt vast op die exit. In beide gevallen komt hij bij deze exit, en in het ene geval springt hij netjes naar het einde van de procedure en in het andere geval levert de exit een error op :?

Ik snap er echt helemaal niks van, omdat het in principe niks moet uitmaken of het programma nu wel of niet procedure2 wel of niet uitvoert, hij komt er niet eens.

Ik heb de search gebruikt en ik heb niks kunnen vinden.

Wie kan mij helpen?????? Want op een exit zou hij toch eigenlijk uberhaupt toch niet moeten kunnen hangen? Het zal dan toch altijd de volgende regel zijn waarop hij vastloopt?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Dit komt van een geheugen corruptie. Ben je aan het spelen met pointers of creeeren/vrijgeven van objecten? Gaat dat wel allemaal goed?

Er bestaat een bug in D7 in de combinatie van een Exit in een Finally. Is dat misschien het geval?

We adore chaos because we like to restore order - M.C. Escher


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
LordLarry schreef op 04 juli 2003 @ 16:42:
Dit komt van een geheugen corruptie. Ben je aan het spelen met pointers of creeeren/vrijgeven van objecten? Gaat dat wel allemaal goed?

Er bestaat een bug in D7 in de combinatie van een Exit in een Finally. Is dat misschien het geval?
Ik ben zeker in die procedure niet bezig met het epslene met pointers of objecten. Wel met een dnamische Array.

Ik gebruik geen try finally daar.

  • whoami
  • Registratie: December 2000
  • Laatst online: 21-08 22:54
Oscar Mopperkont schreef op 04 July 2003 @ 16:55:
[...]


Ik ben zeker in die procedure niet bezig met het epslene met pointers of objecten. Wel met een dnamische Array.
Heb je daar dan ook geen pointers voor nodig?

https://fgheysels.github.io/


Verwijderd

Heb je stop on delphi exceptions aan staan ?

  • joepP
  • Registratie: Juni 1999
  • Niet online
Dynamische arrays zijn een potentiele bron van zeer veel vage foutmeldingen a la "Invaldid Pointer Notification". Ik heb hier laatst ook gruwelijk last van gehad. Het ergste is nog wel als je een dynamische array als resultaat van je function wil teruggeven, en deze functie meerdere keren aanroept. Of nog erger, een record als resultaat met daarin een dynamische array.

Helaas heb ik niet kunnen achterhalen wat de exacte oorzaak was :(

  • Chrizzly
  • Registratie: Januari 2003
  • Laatst online: 04-07 21:50
Een globaal dynamisch array in mijn programma zorgte ook steeds voor problemen.
Zou je niet een if..then..else kunnen toepassen?
Dus if (high(AG)>-1) then <code>;

  • Aetje
  • Registratie: September 2001
  • Laatst online: 18-12-2025

Aetje

Troubleshooting met HAMERRR

Waarschijnlijk wordt door optimalisaties het array opgeruimd nadat het laatste element gedealloceerd is. Vandaar de invalid pointer. Kun je van het array zelf geen index bijhouden? Zo nee zou je er een class voor kunnen declaren...

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


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Waarschijnlijk zit je dan buiten je dynamische array te pielen of iets dergelijks. Kan je anders niet even wat code posten?

We adore chaos because we like to restore order - M.C. Escher


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
De dynamische Array die ik "gebruik" is dus die AG. Daar haal ik telkens het laatste element uit en kot hem dan in. Dat gaat goed.
Ik zat ook te denken dat hij vastliep omdat hij misschien AG weggooit, omdat hij niet meer gebruikt wordt.

Maar als ik de code als volgt maak:
Delphi:
1
2
3
i:=high(AG)
if i<0 then
exit;

Dan krijt i in alle gevallen de juiste waarde mee, -1 in dit geval omdat de array geen elementen meer heeft. De vastloper is dus niet op de High(AG). Maar echt pas zodra exit aangeroepen wordt.

Wat ook vreemd is is dat ik hem in een try..except heb gegooid. Dus zo:
Delphi:
1
2
3
4
5
6
i:=high(AG)
if i<0 then
try
exit;
except
ShowMessage('dus');

En in dat geval laat hij bij zowel de "niet" als de "wel" vastloper "Dus" zien. Alleen loopt hij dus in het ene geval weer wel vast en in het andere niet :?
Als ik debug kom ik echter niet voorbij dit stukje code.

offtopic:
Zit nu thuis, heb code niet bij de hand. Plaats maandag meer code, mocht er zo niet uit te komen zijn.

[ Voor 11% gewijzigd door Oscar Mopperkont op 04-07-2003 19:38 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-08 22:54
Waarom gebruik je geen TObjectList ipv een dynamische array?

Met een TObjectList kan je items adden, removen, .... en die zorgt er ook zelf voor dat hij groeit als het nodig is.

https://fgheysels.github.io/


  • elevator
  • Registratie: December 2001
  • Niet online

elevator

Officieel moto fan :)

Doet de crash zich ook voor als je alle local variables, en alle andere code weghaalt - en je er dus letterlijk alleen if High(AG) < 0 then Exit; van maakt?

Waar haal je die "AG" vandaan? Is dat global of een var parameter?

  • Chrizzly
  • Registratie: Januari 2003
  • Laatst online: 04-07 21:50
En als je if AG = nil then Exit; doet? AG heeft namelijk nog geen pointer begrijp ik, dus er is geen geheugen voor gereserveerd.

  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
whoami schreef op 04 July 2003 @ 19:54:
Waarom gebruik je geen TObjectList ipv een dynamische array?

Met een TObjectList kan je items adden, removen, .... en die zorgt er ook zelf voor dat hij groeit als het nodig is.
Omdat ik deze procedure heb geschreven op het moment dat ik nog helemaal 100% n00b was op gebied van Delphi. Het is te veel werk om het cnaar een objectlist te veranderen.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Omdat ik deze procedure heb geschreven op het moment dat ik nog helemaal 100% n00b was op gebied van Delphi. Het is te veel werk om het cnaar een objectlist te veranderen.
Maar nu is het buggy en crashy... :z

Professionele website nodig?


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Nou breekt mijn klomp! Ik begi er vandaag weer aan, en draai het programma weer om de fout opnieuw op te roepen. Lukt het me niet meer!

Hij geeft nu ook ineens voor High(AG) 0, waar hij eerst -1 gaf. Hij komt dus niet eens meer bij de exit. Verder slaat hij gewoon de rest van de procedure over zodra hij die vergelijking:
Delphi:
1
if High(AG)<0 then

heeft gemaakt. Ik snap er niks meer van. Ik zal wel gek zijn, maar ik zit echt achter 100% exact hetzelfde programma, en hij doet het dus ineens weer. Ik vond het in het begin ook al raar dat hij uberhaupt die foutmelding ineens gaf, omdat hij het eerder niet deed. En ik heb echt, ik zweer het, niks noppes nada in de code veranderd, sinds vrijdag...

Nouja het lijkt allemaal weer te werken. Ik ga nog ff druk bezig om de fout misschien nog op mijn scherm te krijgen, maar ben bang dat dat niet lukt (of bang, is juist mooi, maar ik zit wel met een raar gevoel dan).

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Er schieten mij hier 2 belangrijke quotes binnen:
• "Bugs don't spontaneously disappear. They just hide and pop back up during that important demo for the CEO"
• "If a bug cannot be reproduced it does not exist"


Kies maar uit met welke je het beste kunt leven ;)

Professionele website nodig?


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
curry684 schreef op 07 July 2003 @ 11:18:
Er schieten mij hier 2 belangrijke quotes binnen:
• "Bugs don't spontaneously disappear. They just hide and pop back up during that important demo for the CEO"
• "If a bug cannot be reproduced it does not exist"


Kies maar uit met welke je het beste kunt leven ;)
Hmm ik zit nog te twijfelen ;)

Maar ik blijf het vreemd vinden. Want in principe komen bugs ook niet spontaan, en er is ook heel wat voor nodig om mij te overtuigen dat die fout bij mij er vrijdag wel is, en nu niet, zonder dat er iets veranderd is. Het is dat ik het met eigen ogen zie... maar anders zou ik mezelf voor gek verklaren.

Maar dit is de code van de procedure:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
{Functie heeft als input de Array waarin alle artikelen staan die toegewezen
moeten worden.
Als output geeft het een Array waarin de verdeling van de artikelen over de
zones staat.
Indelen wordt gedaan op basis van List Scheduling}
function TfrMain.ListScheduling(AG: ArtikelArray) : ZoneArray;
type
  HulpRecord =  record
                VrijeLocaties : integer;
                ZoneIndex : integer;
                AantalPicks : integer;
end;

var
  i,j,k,tmp2, GelijkAantalVrijeZones, Verschil, AantalArtikelen,
ZoneMinstePicks, GemAantalPicks : integer;
  HulpArray: Array of HulpRecord;
  tmp : HulpRecord;
  klaar : boolean;

begin
  {Eerst wordt de ZoneArray geinitialiseerd}
  Setlength(Result, speAantalZones.value);//De array krijgt evenveel
plaatsten als dat er zones zijn
  Setlength(HulpArray, speAantalZones.value); //De array krijgt evenveel
plaatsten als dat er zones zijn
  for i:=0 to speAantalZones.value-1 do
  begin
    Setlength(Result[i], TSpinEdit(Clzones[i]).value);//Elke zone krijgt
aantal locaties zoals ingegeven
    HulpArray[i].VrijeLocaties:=TSpinEdit(Clzones[i]).Value; //De HulpArray
houdt bij welke zone hoeveel vrije locaties heeft
    HulpArray[i].ZoneIndex:=i;
    HulpArray[i].AantalPicks:=0;
  end;

  {De HulpArray wordt gesorteerd op aantal vrije locaties}
  for i:=0 to high(HulpArray)-1 do
    for j:=i+1 to high(HulpArray) do
      if (HulpArray[i].VrijeLocaties<HulpArray[j].VrijeLocaties) then //swap
      begin
        tmp := HulpArray[i];
        HulpArray[i] := HulpArray[j];
        HulpArray[j] := tmp;
      end;

  {In de gesorteerde hulparray wordt gekeken welke zones evenveel vrije
  locaties hebben als de zone met het meeste aantal vrij locaties}
  GelijkAantalVrijeZones:=1;
  for i:=1 to high(HulpArray) do
  begin
    if (HulpArray[0].VrijeLocaties = HulpArray[i].VrijeLocaties) then
      inc(GelijkAantalVrijeZones);
  end;

  {Weergeven wat huidige proces is}
  frStatus.lblProces.caption:=('Huidig proces: List Scheduling');
  frStatus.pgbStatus.Position:=0;
  application.ProcessMessages;

  repeat

    {Er wordt gekeken met hoeveel artikelen de zones, met het meeste aantal
vrije
    locaties, gevuld moeten worden om evenveel vrije locaties te hebben als
de
    zones die daarna het meeste aantal vrije locaties hebben}
    If (GelijkAantalVrijeZones < speAantalZones.value) then
      Verschil := HulpArray[GelijkAantalVrijeZones-1].VrijeLocaties -
HulpArray[GelijkAantalVrijeZones].VrijeLocaties
    else
      Verschil := 0;


    {Er wordt bepaald hoeveel artikelen er in totaal aan de zones, met het
meeste
    aantal vrije locaties, toegewezen moeten worden
    Het is +1 omdat je hem opvult totdat er 1 locatie minder vrij is dan in
die
    andere zone}
    If (Verschil <> 0) then
      AantalArtikelen := GelijkAantalVrijeZones*(Verschil+1)
    else
    begin
      AantalArtikelen:=0;
      for i:=0 to (speAantalZones.Value-1) do
        AantalArtikelen := AantalArtikelen + HulpArray[i].Vrijelocaties;
    end;

    {Als AantalArtikelen > nog toe te wijzen artikelen dan is
AantalArtikelen
    gelijk aan nog toe te wijzen artikelen}
    if (AantalArtikelen > (high(AG)+1)) then
      AantalArtikelen:=high(AG)+1;

    {De laatste AantalArtikelen uit de lijst met artikelen die toegewezen
moeten
    worden (AG), worden toegewezen aan de zones, met het meeste
    aantal vrije locaties}
    ZoneMinstePicks:=0;
    i:=(high(AG)-(AantalArtikelen-1));
    repeat

       {De Zone met minste aantal picks mag niet een zone zijn zonder vrije
       locaties}
       if (HulpArray[ZoneMinstePicks].VrijeLocaties = 0) then
       begin
        j:=0;
        repeat
          if (HulpArray[j].VrijeLocaties > 0) then
            ZoneMinstePicks := j;
          j:=j+1;
        until HulpArray[ZoneMinstePicks].VrijeLocaties > 0;
       end;

       {De Zone met minste aantal picks mag niet een zone zijn waaraan al
       Verschil aantal artikelen aan zijn toegewezen}
       if ( (HulpArray[ZoneMinstePicks].VrijeLocaties+1) =
HulpArray[GelijkAantalVrijeZones].VrijeLocaties ) then
       begin
        j:=0;
        repeat
          if ( (HulpArray[j].VrijeLocaties+1) >
HulpArray[GelijkAantalVrijeZones].VrijeLocaties ) then
            ZoneMinstePicks := j;
          j:=j+1;
        until (HulpArray[ZoneMinstePicks].VrijeLocaties+1) >
HulpArray[GelijkAantalVrijeZones].VrijeLocaties;
       end;


       {Bepaal eerst welke zone het minste aantal picks heeft, en waaraan
nog niet
       Verschil #artikelen aan zijn toegewezen}
       for j:=0 to (GelijkAantalVrijeZones-1) do
       begin
        if (GelijkAantalVrijeZones <> speAantalZones.Value) then
        begin
          if ( (HulpArray[j].AantalPicks <
HulpArray[ZoneMinstePicks].AantalPicks) AND ((HulpArray[j].VrijeLocaties+1)
> HulpArray[GelijkAantalVrijeZones].VrijeLocaties) ) then // de plus 1 is
omdat de zone tot zover gevuld moet worden dat er 1 vrije locatie minder is
dan in de zone die daarna het meeste aantal vrije locaties heeft
            ZoneMinstePicks:=j; // gaat dit nog goed als je aan het einde
bent? Dus er zijn nergens meer vrije locaties?
        end
        else
        begin
          if ( (HulpArray[j].AantalPicks <
HulpArray[ZoneMinstePicks].AantalPicks) AND (HulpArray[j].VrijeLocaties >
0) ) then
            ZoneMinstePicks:=j;
        end;
       end;
        {Wijs artikel toe aan de zone met minste picks}
       Result[HulpArray[ZoneMinstePicks].Zoneindex,
HulpArray[ZoneMinstePicks].Vrijelocaties-1] := AG[i];
       HulpArray[ZoneMinstePicks].AantalPicks:= AG[i].Aantal +
HulpArray[ZoneMinstePicks].AantalPicks; //Houd bij hoeveel picks er aan elke
zone zijn toegewezen
       HulpArray[ZoneMinstePicks].VrijeLocaties:=
HulpArray[ZoneMinstePicks].VrijeLocaties-1;

       {Het toegewezen artikel wordt uit de AGArray verwijderd}
       for k:=i to (high(AG)-1) do
       begin
        AG[k]:= AG[k+1];
       end;
       Setlength(AG, high(AG));

    until i=high(AG)+1;

    {Als alle artikelen al zijn toegewezen dan moet de functie beeindigd
worden}
    if (high(AG)<0) then
      exit;


    {De laatste AantalArtikelen uit de lijst met artikelen moeten toegewezen
    moeten worden (ArtikelGegevens), zijn toegewezen aan de zones, met het
    meeste aantal vrije locaties.
    Aan elke zone, die nu 1 vrije locatie meer hebben dan de zones waar net
    artikelen aan toegewezen zijn, wordt nu 1 artikel toegewezen met
ongeveer
    evenveel picks als dat die andere zones hebben.

    Eerst wordt hoeveel picks de zones gemiddeld hebben waaraan zojuist
    artikelen aan zijn toegewezen.}
    GemAantalpicks:=0;
    for j:=0 to (GelijkAantalVrijeZones-1) do
    begin
      GemAantalPicks := GemAantalPicks + HulpArray[j].AantalPicks;
    end;
    GemAantalPicks := (GemAantalPicks div GelijkAantalVrijeZones);

    {Er wordt bepaald aan welke zones er 1 artikel toegewezen moet worden}
    {De HulpArray wordt gesorteerd op aantal vrije locaties}
    for i:=0 to high(HulpArray)-1 do
      for j:=i+1 to high(HulpArray) do
        if (HulpArray[i].VrijeLocaties < HulpArray[j].VrijeLocaties) then
//swap
        begin
          tmp := HulpArray[i];
          HulpArray[i] := HulpArray[j];
          HulpArray[j] := tmp;
        end;

    {In de gesorteerde hulparray wordt gekeken welke zones evenveel vrije
    locaties hebben als de zone met het meeste aantal vrij locaties}
    GelijkAantalVrijeZones:=1;
    for i:=1 to high(HulpArray) do
     if (HulpArray[0].VrijeLocaties = HulpArray[i].VrijeLocaties) then
      inc(GelijkAantalVrijeZones);

    {Aan deze zones wordt nu telkens 1 artikel toegewezen}
    for i:=0 to (GelijkAantalVrijeZones-1) do
    begin
      j:=0;
      tmp2:= MaxInt;//moet heel hoog getal zijn
      repeat
        klaar := false;
        k:=abs(AG[j].Aantal-GemAantalPicks);
        if (k < tmp2) then
          tmp2:=k
        else
        begin
          Result[HulpArray[i].Zoneindex, HulpArray[i].Vrijelocaties-1] :=
AG[j-1];
          HulpArray[i].AantalPicks:= AG[j-1].Aantal +
HulpArray[i].AantalPicks; //Houd bij hoeveel picks er aan elke zone zijn
toegewezen
          HulpArray[i].VrijeLocaties:= HulpArray[i].VrijeLocaties-1;
          for k:=j-1 to (high(AG)-1) do
            AG[k]:= AG[k+1];
          Setlength(AG, high(AG));
          klaar:=true
        end;
        j:=j+1;
      until (klaar = true) or (j=high(AG)); //Wat als het laatste het geval
is????? Dan is er nog niks toegewezen, maar dat is wel bijna onmogelijk
volgens mij
    end;

    {In de gesorteerde hulparray wordt gekeken welke zones evenveel vrije
    locaties hebben als de zone met het meeste aantal vrij locaties}
    GelijkAantalVrijeZones:=1;
    for i:=1 to high(HulpArray) do
      if (HulpArray[0].VrijeLocaties = HulpArray[i].VrijeLocaties) then
        inc(GelijkAantalVrijeZones);


  {Is onderstaande het geval dan hebben alle zones nog evenveel vrije
locatie
  locaties over en kan de rest van de artikelen worden toegewezen op basis
van
  list scheduling}
  until GelijkAantalVrijeZones = speAantalzones.value;

  {Als alle artikelen al zijn toegewezen dan moet de functie beeindigd
worden}
  if (high(AG)<0) then
    exit;

  ZoneMinstePicks:=0;
  repeat
    {De Zone met minste aantal picks mag niet een zone zijn zonder vrije
    locaties}
    if (HulpArray[ZoneMinstePicks].VrijeLocaties = 0) then
    begin
      j:=0;
      repeat
        if (HulpArray[j].VrijeLocaties > 0) then
        ZoneMinstePicks := j;
        j:=j+1;
      until HulpArray[ZoneMinstePicks].VrijeLocaties > 0;
    end;

    for j:=0 to (speAantalZones.Value-1) do
    begin
      if ( (HulpArray[j].AantalPicks <
HulpArray[ZoneMinstePicks].AantalPicks) AND (HulpArray[j].VrijeLocaties >
0) ) then // de plus 1 is omdat de zone tot zover gevuld moet worden dat er
1 vrije locatie minder is dan in de zone die daarna het meeste aantal vrije
locaties heeft
        ZoneMinstePicks:=j; // gaat dit nog goed als je aan het einde bent?
Dus er zijn nergens meer vrije locaties?
    end;
    {Wijs artikel toe aan de zone met minste picks}
    Result[HulpArray[ZoneMinstePicks].Zoneindex,
HulpArray[ZoneMinstePicks].Vrijelocaties-1] := AG[0];
    HulpArray[ZoneMinstePicks].AantalPicks:= AG[0].Aantal +
HulpArray[ZoneMinstePicks].AantalPicks; //Houd bij hoeveel picks er aan elke
zone zijn toegewezen
    HulpArray[ZoneMinstePicks].VrijeLocaties:=
HulpArray[ZoneMinstePicks].VrijeLocaties-1;

    {Het toegewezen artikel wordt uit de AGArray verwijderd}
    for k:=0 to (high(AG)-1) do
     AG[k]:= AG[k+1];
    Setlength(AG, high(AG));

  until high(AG)<0;

  frStatus.pgbStatus.Position:=100;
  application.ProcessMessages;


end;

In regel 175/176 staat dus he stukje code waar het mis ging. Waar dat nu dus niet meer fout gaat. Echter zodra de vergelijking gemaakt wordt, en High(AG)=0 dan gaat hij dus niet naar de exit, maar springt hij wel meteen naar het einde van de procedure. Is dat een optimalisatie van Delphi zelf? Want hij hoeft daarna inderdaad eigenlijk niks meer te doen, alle loopjes zijn van 0 tot 0, maar dit is pas de eerste keer met debuggen dat ik merk dat Delphi zo vooruit kijkt en dus overal langsspringt.
Het is wel slim, maar of het echt handig is vraag ik me af.

Ik zal ook even geven wat AG nu is:
Delphi:
1
2
3
4
5
6
  ArtikelRec =  record
                Index: integer;
                Naam: String;
                Aantal: Integer;
                end;
  ArtikelArray = Array of ArtikelRec;


Sorry voor de lappen met tekst, maar sommigen wilde het weten, dus kan ik het net goed maar geven. Vraag me af of iemand er echtw ijs uit kan komen. Want het is nogal specifiek, en het is maar een klein deel van een groter geheel EN dit was zo'n beetje mijn eerste functie ooit in delphi, dus echt netjes is het allemaal ook niet.


Zie trouwens dat ik het de hele tijd over procedure had, maar het was een functie. Hoop niet dat dat heel veel uitmaakt voor mijn verhaal? Mijn excuses in ieder geval.

[ Voor 96% gewijzigd door Oscar Mopperkont op 07-07-2003 12:06 ]


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
AAARGHHHH En de fout duikt weer op... Het loopt vast op de vergelijking of op de exit, ik weet het niet zeker. Want als ik:
Delphi:
1
if High(AG)<0 then


Vervang door:
Delphi:
1
2
3
m:=High(AG)
if m<0 then
exit

Dan krijgt m waarde -1 en klapt hij er, nadat de regel op de vergelijking staat en ik op F8/F7 druk, eruit.

Ik heb wat screendumps gemaakt.

Als het goed gaat ziet het er zo uit:
Afbeeldingslocatie: http://home.student.utwente.nl/o.v.lamme/VoorGoed.JPG[/url]

En daarna springt ie door naar:
Afbeeldingslocatie: http://home.student.utwente.nl/o.v.lamme/NaGoed.JPG[/url]

Als het fout gaat ziet het er zo uit:
Afbeeldingslocatie: http://home.student.utwente.nl/o.v.lamme/VoorFout.JPG[/url]

En daarna springt hij naar de foutmelding:
Afbeeldingslocatie: http://home.student.utwente.nl/o.v.lamme/NaFout.JPG[/url]

In beide gevallen is AG nog aanwezig in de watchlist, en high(AG) krijgt een waarde mee, dus die test moet goed gaan. Hij loopt denk ik echt vast op die exit. Het verschil is te zien in de watch list, waaruit blijkt dat bij de foutmelding AG weggegooid wordt, hij is undeclared.
Misschien zit in dt laatste ook wel de oplossing, maar hoe declare ik hem dan?

[ Voor 11% gewijzigd door Oscar Mopperkont op 10-07-2003 10:36 ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

offtopic:
De URL waar alle plaatjes naar linken heeft volgens mij geen ruk met dit probleem van doen?

Professionele website nodig?


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
curry684 schreef op 10 juli 2003 @ 10:35:
offtopic:
De URL waar alle plaatjes naar linken heeft volgens mij geen ruk met dit probleem van doen?
offtopic:
Welke URL ;), het programma dat ik maak "lost" overigens wel het probleem op waarnaar deze plaatjes per ongeluk gelinkt stonden.

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 21:11

Reptile209

- gers -

Zou het probleem kunnen zitten in het gebruik van Result[] door de hele functie heen? In line 29 heb je het over Result[i], terwijl voorbij de helft van de code (ergens) Result tweedimensionaal wordt. Probeer je functie eens aan te passen met een tijdelijke array die je aan het einde toewijst aan Result. Dan kan Delphi nog wat boundary-checking voor je doen.

Hoe is ZoneArray gedefinieerd?

Wat het wel en niet kunnen reproduceren van de fout betreft: met een beetje mazzel heb je een situatie waar het misbruik van geheugen geen probleem oplevert. Door wat wijzigingen kom je daar wel in terecht, en na een herstart van Delphi wordt het weer anders. Heb zelf ook wel eens het een en ander over zijn nek laten gaan na wat gepruts met ongeldig geheugen. Herstart van Delphi brengt je in elk geval weer in "schoner" geheugen. En dan nog eens dubbelchecken hoe je verwijzingen lopen natuurlijk :).

edit:
Wordt na het lezen van je code wel een beetje gaar van alle BladiblaZones ;)

[ Voor 6% gewijzigd door Reptile209 op 10-07-2003 10:50 ]

Zo scherp als een voetbal!


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Reptile209 schreef op 10 July 2003 @ 10:49:
Zou het probleem kunnen zitten in het gebruik van Result[] door de hele functie heen? In line 29 heb je het over Result[i], terwijl voorbij de helft van de code (ergens) Result tweedimensionaal wordt. Probeer je functie eens aan te passen met een tijdelijke array die je aan het einde toewijst aan Result. Dan kan Delphi nog wat boundary-checking voor je doen.
Maar dan zou de vastloper moeten komen doordat ik iets toewijs aan Result, wat buiten de boundary van Result is, toch? Waarom zou hij dan op de exit vastlopen? Want daar wordt niks toegewezen aan Result.
Hoe is ZoneArray gedefinieerd?
Delphi:
1
2
3
4
5
6
7
  ArtikelRec =  record
                Index: integer;
                Naam: String;
                Aantal: Integer;
                end;
  ArtikelArray = Array of ArtikelRec;
  ZoneArray = Array of ArtikelArray; 


Wat het wel en niet kunnen reproduceren van de fout betreft: met een beetje mazzel heb je een situatie waar het misbruik van geheugen geen probleem oplevert. Door wat wijzigingen kom je daar wel in terecht, en na een herstart van Delphi wordt het weer anders. Heb zelf ook wel eens het een en ander over zijn nek laten gaan na wat gepruts met ongeldig geheugen. Herstart van Delphi brengt je in elk geval weer in "schoner" geheugen. En dan nog eens dubbelchecken hoe je verwijzingen lopen natuurlijk :).
edit:
Wordt na het lezen van je code wel een beetje gaar van alle BladiblaZones ;)
Ik word er zelf ook ramgek van! 8)7 Zone'tje zone'tje daar....

Kan de fout ook misschien komen door, waaraan ik de functie toewijs. Het resultaat van de fnctie is immers een zonearray die ik meegeef aan een andere zonearray:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
  {ZoneGegevens wordt geinitialiseerd}
  Setlength(ZoneGegevens, speAantalZones.value);
//De array krijgt evenveel plaatsten als dat er zones zijn
  for i:=0 to speAantalZones.value-1 do
    Setlength(ZoneGegevens[i], TSpinEdit(Clzones[i]).value);
//Elke zone krijgt aantal locaties zoals ingegeven
 
  {Er wordt normaal ListScheduling gedaan, mits gebruiker heeft aangegeven
  dat er een SimeleToewijzing moet plaatsvinden}
  if cbSimpeleToewijzing.state=cbUnChecked then
    ZoneGegevens:= ListScheduling(ArtikelGegevens)

In ListScheduling wordt de lentgte van Result op exact dezelfde wijze toegewezen. En het gaat eigenlijk ook altijd goed, behalve in 1 bepaald geval dus...


Waarom wordt deze message nu zo breed weergegeven? Mijn eerdere megacode wordt wel afgekapt? :?

[ Voor 4% gewijzigd door Oscar Mopperkont op 10-07-2003 11:22 ]


  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 21:11

Reptile209

- gers -

Oscar Mopperkont schreef op 10 July 2003 @ 11:11:
[...]

Maar dan zou de vastloper moeten komen doordat ik iets toewijs aan Result, wat buiten de boundary van Result is, toch? Waarom zou hij dan op de exit vastlopen? Want daar wordt niks toegewezen aan Result.
Klopt, maar bij Exit (of eigenlijk: het verlaten van je procedure) wordt Result op de stack gemikt om terug te sturen naar de aanroepende code. En dan zou er dus wat mis kunnen gaan. Sowieso klopt het dus niet dat je Result in één functie zowel 1 als 2 dimensionaal gebruikt. Ik weet niet of Delphi een goede check heeft op de toewijzing aan Result. Kan best zijn dat dat wat de compiler betreft allemaal één pointer is waar hij wat array-math op loslaat. En dan zou de toewijzing wel goed kunnen gaan.
Nog een mogelijkheid waarom de exit juist misloopt: de stackpointer moet terug (vooruit? whatever...) springen naar de plek waar het adres van de aanroepende code staat. Als Result die vernaggeld heeft, heb je de poppen aan het dansen.

Waarom wordt deze message nu zo breed weergegeven? Mijn eerdere megacode wordt wel afgekapt? :?
Edit de comments even een regel omhoog of omlaag, probleem opgelost :)

[ Voor 9% gewijzigd door Reptile209 op 10-07-2003 11:20 ]

Zo scherp als een voetbal!


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Reptile209 schreef op 10 juli 2003 @ 11:18:
[...]

.. Sowieso klopt het dus niet dat je Result in één functie zowel 1 als 2 dimensionaal gebruikt.
Result is een 2-dimensionaal Array. Ik moet van beide dimensies de lengte vaststellen. Dus ik roep hem in het begin een keer 1 dimensionaal aan om die dimensie vast te stellen. Dat is toch niet door elkaar gebruiken van 1 en 2 dimensionaal. Volgens mij kan dat niet anders.
Result is een ZoneArray. De eerste dimensie geeft aan hoeveel zones er zijn, de tweede dimensie geeft aan hoeveel plaatsen er in elke zone zijn. Dus ik oet eerst zeggen dat er x zones zijn door Setlength(Result,x)... Vervolgens voor elke zone aantal plaatsten Setlength(Result[0],...)....SetLength(Result[x-1],...)
Ik weet niet of Delphi een goede check heeft op de toewijzing aan Result. Kan best zijn dat dat wat de compiler betreft allemaal één pointer is waar hij wat array-math op loslaat. En dan zou de toewijzing wel goed kunnen gaan.
Nog een mogelijkheid waarom de exit juist misloopt: de stackpointer moet terug (vooruit? whatever...) springen naar de plek waar het adres van de aanroepende code staat. Als Result die vernaggeld heeft, heb je de poppen aan het dansen.
Kan ik daar iets aan doen? Dus voor die exit ervoor zorgen dat ik zeker weten dat die stackpointer goed staat?
Edit de comments even een regel omhoog of omlaag, probleem opgelost :)
Dat is een oplossing ja, inmiddels ook gedaan. Maar waarom deed ie het?

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 21:11

Reptile209

- gers -

Oscar Mopperkont schreef op 10 juli 2003 @ 11:29:
[...]

Oscar tikt Reptile209 terecht op de vingers
Klopt, daar had ik even overheen gelezen :+. Wat je daar doet moet kunnen.
[...]

Kan ik daar iets aan doen? Dus voor die exit ervoor zorgen dat ik zeker weten dat die stackpointer goed staat?
Uit de Delphi Help (Dynamic Arrays): Assigning to a dynamic-array index (for example, MyFlexibleArray[2] := 7) does not reallocate the array. Out-of-range indexes are not reported at compile time.. Code ervoor is: SetLength(MyFlexibleArray, 1);

De stackpointer staat per definitie (voor de programmeur) goed, mits je geen geheugenfouten maakt. Er zit dus - gok ik - ergens een fout dat een van je arrays buiten zijn gereserveerde geheugen zit. Maar waar kan ik zo ook niet vinden. De hard-core bible of debugging zegt: alles met commentaar uitzetten en dan blok voor blok weer aanzetten. Kijken waar het misgaat... :)
[...]

Dat is een oplossing ja, inmiddels ook gedaan. Maar waarom deed ie het?
Wat je niet ziet, bestaat niet. :D Geen idee, hij hoort ze niet af te breken volgens mij.

[ Voor 6% gewijzigd door Reptile209 op 10-07-2003 11:47 ]

Zo scherp als een voetbal!


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
JAAAAAAAAAAAAH!!! :)

Ik heb de fout ontdekt, en er (hoop ik) er nu goed uitgehaald!

Ergens anders in het programma maak ik een fout met een dynamische array. Ook daar heb ik een functie met als output een array die aan een andere array wordt toegewezen.
Dus zoiets
Delphi:
1
BlahblahArray:=EenOfandereFunctie;

Nu vergat ik eerst die BlahBlahArray te initialiseren door niet zijn lengte vast te stellen. Deze fout zorgt er dus blijbaar voor dat die stackpointer "verkeerd" staat. Alleen resulteerde dit tot nu toe nooit in fouten. Sterker nog, afgelopen maandag kwam dit bij dezelfde instellingen niet naar voren. daarom had ik de fout denk ik ook nooit ontdekt.

In ieder geval onwijs bedankt voor alle moeite!

Reptile209 had het dus inderdaad bij het goede eind dat ik ergens een array buiten het gereserveerde geheugen had staan, maar die array zat dus heel ergens anders, en zorgde vreemd genoeg nooit voor fouten.

edit:

De fout hadden jullie ook overigens nooit kunnen vinden, het zat dus totaal eregns anders in het programma, en er werd in deze procedure ook niks mee gedaan.

[ Voor 11% gewijzigd door Oscar Mopperkont op 10-07-2003 12:06 ]


  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 21:11

Reptile209

- gers -

[doemscenario]
Let wel ff op dat het veranderen van code buiten je functie er ook toe zou kunnen leiden dat de functie of een aantal geheugenadressen verplaatst worden, waardoor de fout er nog wel is, maar nu niet optreedt. En dan komt 'ie later alsnog bovenborrelen.
Dus een stap-voor-stap controle van alle indices en hun maximale waarde is nog wel aan te bevelen :).
[/doemscenario]

Wel mooi dat je die gevonden hebt!

Zo scherp als een voetbal!


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Oscar Mopperkont schreef op 10 July 2003 @ 12:05:
Reptile209 had het dus inderdaad bij het goede eind dat ik ergens een array buiten het gereserveerde geheugen had staan, maar die array zat dus heel ergens anders, en zorgde vreemd genoeg nooit voor fouten.
LordLarry schreef op 04 July 2003 @ 19:16:
Waarschijnlijk zit je dan buiten je dynamische array te pielen of iets dergelijks. Kan je anders niet even wat code posten?
Dat zei ik toch al 6 dagen geleden? :P

We adore chaos because we like to restore order - M.C. Escher


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
LordLarry schreef op 10 juli 2003 @ 12:33:

Dat zei ik toch al 6 dagen geleden? :P
Idd je hebt gelijk. Maar ik had gewoon niet door dat et ook een array kon zijn die totaal ergens anders in het programma staat en die op dat moment ook niet gebruikt wordt.

Maar ook hulde voor LordLarry _/-\o_

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Oscar Mopperkont schreef op 10 July 2003 @ 12:51:
[...]


Idd je hebt gelijk. Maar ik had gewoon niet door dat et ook een array kon zijn die totaal ergens anders in het programma staat en die op dat moment ook niet gebruikt wordt.

Maar ook hulde voor LordLarry _/-\o_
Is overgens niet waarom ik het net poste hoor :D, maar evengoed bedankt :)

We adore chaos because we like to restore order - M.C. Escher


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
:( :( :( :(

8)7

En ja hoor daar is ie weer! Ik heb ook een wizard bij mijn programma zitten, en als ik mijn hoofdformulier invul via de wizard (meer is het niet), dan
duikt de fout weer op...

De fout is wel nog steeds weg, voor zoals ik hem gister vond. Dus invullen via hoofdformulier. Er zal dus wel wat fout gaan met geheugen. Nu heb ik op 1 of andere cd een progje memproof staan. Weet niet goed wat je ermee moet/kan. Maar iig als ik het programma via memproof start en run, dan duikt de fout niet op! Ik word er echt helemaal gek van. Want ik heb nu natuurlijk gekeken of ik misschien ergens anders nog eenzelfde fout heb staan, maar kan echt niks vinden.

Zijn daar misschien tools voor om eventueel geheugenfouten op te sporen?

Reptile209 had mij al gewaarschuwd zie ik...
[doemscenario]
Let wel ff op dat het veranderen van code buiten je functie er ook toe zou kunnen leiden dat de functie of een aantal geheugenadressen verplaatst worden, waardoor de fout er nog wel is, maar nu niet optreedt. En dan komt 'ie later alsnog bovenborrelen.
Dus een stap-voor-stap controle van alle indices en hun maximale waarde is nog wel aan te bevelen .
[/doemscenario]

[ Voor 26% gewijzigd door Oscar Mopperkont op 11-07-2003 10:03 ]


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 17:28

alienfruit

the alien you never expected

Ja hoor: http://www.automatedqa.com/products/aqtime.asp
Werkt tot heden perfect! :)

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

MemProof is het kleine (en gratis) broertje van AQTime, maar is wat beperkt en zal lang niet zoveel vinden als zijn grote broertje. Ook is er (volgensmij) geen D7 versie van. Ben je niet vergeten om de speciale project instellingen te doen voordat je memproof hebt gebruikt? Anders zie je niet veel. Zie daarvoor de help van memproof.

We adore chaos because we like to restore order - M.C. Escher


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
LordLarry schreef op 11 July 2003 @ 10:39:
MemProof is het kleine (en gratis) broertje van AQTime, maar is wat beperkt en zal lang niet zoveel vinden als zijn grote broertje. Ook is er (volgensmij) geen D7 versie van. Ben je niet vergeten om de speciale project instellingen te doen voordat je memproof hebt gebruikt? Anders zie je niet veel. Zie daarvoor de help van memproof.
Ik heb nog helemaal niks ingesteld. Ik ging uiteraadr zonder iets te doen meteen aan de gang. Maar het "vreemde" was dus dat de fout binnen memproof niet optreed. Maar dat is waarschijnlijk om de reden die reptile al gaf (zijn doemscenario).


Werkt die evaluatie copy van AQtime volledig, danwel waarschijnlijk voldoende voor mij?

[ Voor 9% gewijzigd door Oscar Mopperkont op 11-07-2003 10:45 ]


  • Oscar Mopperkont
  • Registratie: Februari 2001
  • Laatst online: 03-08-2024
Oscar Mopperkont schreef op 11 July 2003 @ 10:44:
[...]


Ik heb nog helemaal niks ingesteld. Ik ging uiteraadr zonder iets te doen meteen aan de gang. Maar het "vreemde" was dus dat de fout binnen memproof niet optreed. Maar dat is waarschijnlijk om de reden die reptile al gaf (zijn doemscenario).


Werkt die evaluatie copy van AQtime volledig, danwel waarschijnlijk voldoende voor mij?
Ik zit nu wat te freewheelen met memproof (ver oude versie volgens mij) en in de debug window krijg ik zulke dingen te zien:
---- Exception stack trace ----
620482A2 - MPError in (-1)
62048E09 - MPError in (-1)
6204981E - MPError in (-1)
62409B8D - RegisterItems in (-1)
00414D1C - in (-1)
004462C5 - in (-1)
0041BCF2 - in (-1)
77D37AD7 - SetWindowPlacement in (-1)
77D3CCD4 - DefRawInputProc in (-1)
77D156B6 - IsWindowVisible in (-1)
77D15A71 - SendMessageA in (-1)
004466AF - in (-1)
Exception C0000005 ACCESS_VIOLATION at 620482A2
Dingen als MPError(-1) en ACCES VIOLATION lijken mij niet echt bevordelijk. Maar hoe achterhaal je je nu met dat programma waar die fout dan in je programma zit?

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

at 620482A2
Menu -> Search -> Find Error en toets daar het adres in.

Als de code veranderd verschuiven de adressen, dus zorg dat je dezelfde versie hebt. Als het adres niets zinnigs geeft pak je die daarvoor.

[ Voor 3% gewijzigd door LordLarry op 11-07-2003 11:27 ]

We adore chaos because we like to restore order - M.C. Escher

Pagina: 1