Access Violation nach der letzten Anweisung?

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
alfware17
Beiträge: 226
Registriert: Di 14. Dez 2010, 23:27

Access Violation nach der letzten Anweisung?

Beitrag von alfware17 »

Ich habe ein (noch in Entwicklung befindliches) Programm, welches bei größeren Eingabedateien einen merkwürdigen Abbruch bringt. Bei 5000 Zeilen oder 50000 Zeilen tritt das noch nicht auf, aber zB bei 500000 Zeilen. Der Lazarus Debugger steht auf dem leztzten END. und sagt "Access violation" bei einer komischen Adresse mit vielen FFFF. Nun möchte ich für meine Units (zB OptIO) nicht die Hand ins Feuer legen, aber ich rufe doch noch gar nichts groß davon auf? Die eigentlichen Verbrechen äh Tests sollen noch kommen. Wie kann ich aber herausfinden, was hier scheinbar verboten ist?
Dateianhänge
mergesort.zip
(206.79 KiB) 172-mal heruntergeladen

Warf
Beiträge: 2183
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Access Violation nach der letzten Anweisung?

Beitrag von Warf »

Das klingt als würdest du dir deinen Stack zerhauen. Passiert in etwa das gleiche wie hier?

Code: Alles auswählen

program Test;

procedure Smash;
var i: QWord;
begin
  FillChar(i, 1024, $FF); // SizeOf(i) = 8 => 1016 bytes über i hinaus auf dem stack werden mit müll befüllt
end; // Stack zerschossen daher ist rücksprungspointer jetzt kaputt und es kracht beim exit aus der funktion

begin
  Smash;
end. 

alfware17
Beiträge: 226
Registriert: Di 14. Dez 2010, 23:27

Re: Access Violation nach der letzten Anweisung?

Beitrag von alfware17 »

Oh, Fehler gefunden... Ich habe nur 255 Zähler(Intervalle) und habe versucht mit 220+i zu viele zu benutzen. Ich habe Anzahl Verfahren (1..9) und Anzahl Zwischendateien (bei 50.000 / 10.000 = 5 war alles gut, bei 500.000 / 10.000 war er dann geplatzt) verwechselt. Wobei das Zählen hat er durchaus noch gemacht und mir wahrscheinlich nur "totes Fleisch" in der ZEIT Unit überschrieben, Aber aus irgendwelchen Gründen hat er dann beim Programmende aufgepaßt. Spannenderweise war meine 10.000 nur testweise reingekommen, eigentlich hätte ich immer mit 100.000 gebaut und das wahrscheinlich erst beim Abnahmetest gemerkt.

Die Anzahl Intervalle kann/will ich nicht erhöhen - aber spannend wenn so ein Programm auch mal 100 braucht... Meine Intervall-Summierung

Code: Alles auswählen

Intervall_Summe([221..229])
war übrigens schon auf der richtigen Spur, 229 war der Wunsch, allerdings habe ich Schrott produziert und so auch 256 aufwärts. Und da ich das nicht erhöhen kann/will nur dafür, wird eben gewohnt in einer Double addiert (chunksort)

Code: Alles auswählen

PROCEDURE SortiereChunks(CONST ChunkFiles: TStringList; SortierVerfahren: INTEGER);
VAR
  i: INTEGER;
  outName: STRING;
BEGIN
  FOR i := 0 TO ChunkFiles.Count-1 DO BEGIN
    zeit_nr2 := 220 + SortierVerfahren;
    t:=Intervall_Start(zeit_nr2);
    IF StartStopAus THEN Writeln(t, ' Sortiere Chunk ', ChunkFiles[i]);
    outName := ChunkFiles[i];
    CASE SortierVerfahren OF
      1: Verfahren1N(ChunkFiles[i], outName);
      2: Verfahren2N(ChunkFiles[i], outName);
      3: Verfahren3N(ChunkFiles[i], outName);
      4: Verfahren4N(ChunkFiles[i], outName);
      5: Verfahren5N(ChunkFiles[i], outName);
      6: Verfahren6N(ChunkFiles[i], outName);
      7: Verfahren7N(ChunkFiles[i], outName);
      8: Verfahren8N(ChunkFiles[i], outName);
      9: Verfahren9 (ChunkFiles[i], outName);
    ELSE
      Writeln('Unbekanntes Sortierverfahren in SortiereChunks: ', SortierVerfahren);
    END;
    t:=Intervall_Stop(zeit_nr2);
    IF StartStopAus THEN Writeln(t, ' Ende Chunk ', ChunkFiles[i], ' Dauer ', Intervall_Dauer(zeit_nr2));
    IF DEBUG THEN Writeln('Sort Chunk ', i, ' Verfahren ', Sortierverfahren, ' vorher ', StrDouble(chunksort), ' ', Intervall_Format(chunksort));
    chunksort := chunksort + Intervall_Wert(zeit_nr2);
    IF DEBUG THEN Writeln('Sort Chunk ', i, ' Verfahren ', Sortierverfahren, ' nachher ', StrDouble(chunksort), ' ', Intervall_Format(chunksort));
  END;
END;

Antworten