Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - AccessViolation beim Ausführen des Programms
FlySource - Mi 30.05.12 21:40
Titel: AccessViolation beim Ausführen des Programms
Hallo User!
Ich habe hier mal ein neues Thema geöffnet, weil ich nichts passendes gefunden habe, zudem hoffe ich, dass ich im richtigen Unterforum gelandet bin.
Ich schreibe im Moment an einem Programm, das Bücherdaten verwaltet auf Basis einer TList.
Mein Problem liegt darin, dass ich die komplette Bücherdatenbank löschen will und zwar mit dem destructor destroy aus uTDatenbank, aber das Programm mir den Fehler anzeigt:
uTBuecherdatenbank.pas(23): Methode 'Destroy' verbirgt virtuelle Methode vom Basistyp 'TObject'
Ich habe keine Ahnung was ich mit dem Fehler anfangen soll und woran es liegt.
Delphi-Quelltext
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:
| UNIT uTBuecherdatenbank;
interface
uses mList, uTBuch, SysUtils;
type TBuecherdatenbank = class
protected dieListe : TList;
public constructor create; virtual; procedure buchEinfuegen (pBuch: TBuch); virtual; procedure buchLoeschen (pISBN: string); virtual; procedure buchVerkaufen (pISBN: string); virtual; procedure setzeAufErstes; virtual; function gibISBN (pAutor: string; pTitel: string) : string; virtual; function gibNaechstes : string; virtual; function gibPreis (pISBN: string) : integer; virtual; destructor destroy;virtual;
end;
implementation
constructor TBuecherdatenbank.create; begin dieListe := TList.create; end;
procedure TBuecherdatenbank.buchEinfuegen (pBuch: TBuch); var hilfsobjekt: TBuch; fertig: boolean; begin fertig:=false; dieListe.toFirst; while dieListe.hasAccess = true do begin hilfsobjekt:=TBuch(dieListe.getObject); if hilfsobjekt.GibISBN > pBuch.GibISBN then begin dieListe.insert(pBuch); fertig:=true; break; end; dieListe.next; end; if fertig=false then dieListe.append(pBuch);
end;
procedure TBuecherdatenbank.buchLoeschen (pISBN: string); var hilfsobjekt: TBuch; begin dieListe.toFirst; while dieListe.hasAccess = true do begin hilfsobjekt := TBuch(dieListe.getObject); if (hilfsobjekt.GibISBN = pISBN) then begin dieListe.remove; break; end; dieListe.next; end; end;
procedure TBuecherdatenbank.buchVerkaufen (pISBN: string); var hilfsobjekt: TBuch; anz: integer; begin dieListe.toFirst;
while dieListe.hasAccess = true do begin hilfsobjekt := TBuch(dieListe.getObject);
if hilfsobjekt.GibISBN = pISBN then begin anz := hilfsobjekt.GibAnzahl; anz := anz-1; hilfsobjekt.SetzeAnzahl(anz); dieListe.setObject(hilfsobjekt);
break; end; dieListe.next; end; end;
procedure TBuecherdatenbank.setzeAufErstes; begin dieListe.toFirst; end;
function TBuecherdatenbank.gibISBN (pAutor: string; pTitel: string) : string; var hilfsobjekt: TBuch; begin dieListe.toFirst; gibISBN:='nicht vorhanden'; while dieListe.hasAccess = true do begin hilfsobjekt := TBuch(dieListe.getObject); if (hilfsobjekt.GibAutor = pAutor) and (hilfsobjekt.GibTitel = pTitel) then begin gibISBN:=hilfsobjekt.GibISBN; break; end; dieListe.next; end; end;
function TBuecherdatenbank.gibNaechstes : string; var hilfstring: string; hilfsobjekt: TBuch; begin if dieListe.hasAccess=true then begin hilfsobjekt := TBuch(dieListe.getObject); hilfstring := hilfsobjekt.GibTitel + '; ' + hilfsobjekt.GibAutor + '; ' + hilfsobjekt.GibISBN + '; ' +
inttostr(hilfsobjekt.GibPreis) + '; ' + inttostr(hilfsobjekt.GibAnzahl); dieListe.next; gibNaechstes:=hilfstring; end else gibNaechstes:='';
end;
function TBuecherdatenbank.gibPreis (pISBN: string) : integer; var hilfsobjekt: TBuch; begin dieListe.toFirst; gibPreis:=0; while dieListe.hasAccess = true do begin hilfsobjekt := TBuch(dieListe.getObject); if (hilfsobjekt.GibISBN = pISBN) then begin gibPreis:=hilfsobjekt.GibPreis; break; end; dieListe.next; end; end;
destructor TBuecherdatenbank.destroy; begin dieliste.toFirst; while dieliste.hasAccess=true do begin dieliste.remove; dieliste.next; if dieliste.hasAccess=false then break; end; end;
end. |
Die vorgegebene Liste:
Delphi-Quelltext
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:
|
UNIT mList;
interface type TNode = class private content: TObject; nextNode: TNode; constructor create(pObject: TObject); procedure setContent(pObject: TObject); procedure setNext(pNext: TNode); function getContent: TObject; function getNext: TNode; destructor destroy; override; end;
TList = class private first: TNode; tail: TNode; current: TNode; public constructor create; virtual; function isEmpty: boolean; virtual; function hasAccess: boolean; virtual; procedure next; virtual; procedure toFirst; virtual; procedure toLast; virtual; function getObject: TObject; virtual; procedure setObject(pObject: TObject); virtual; procedure append(pObject: TObject); virtual; procedure insert(pObject: TObject); virtual; procedure concat(pList: TList); virtual; procedure remove; virtual; destructor destroy; override; end;
implementation
constructor TNode.create(pObject: TObject); begin content := pObject; nextNode := nil; end;
procedure TNode.setContent(pObject: TObject); begin content := pObject; end;
procedure TNode.setNext(pNext: TNode); begin nextNode := pNext; end;
function TNode.getContent: TObject; begin result := content; end;
function TNode.getNext: TNode; begin result := nextNode; end;
destructor TNode.destroy; begin inherited destroy; end;
constructor TList.create; begin tail := TNode.create(nil); first := tail; tail.setNext(tail); current := first; end;
function TList.isEmpty: boolean; begin result := first = tail; end;
function TList.hasAccess: boolean; begin result := not self.isEmpty and (current <> tail); end;
procedure TList.next; begin if self.hasAccess then current := current.getNext; end;
procedure TList.toFirst; begin if not self.isEmpty then current := first; end;
procedure TList.toLast; begin if not self.isEmpty then current := tail.getNext; end;
function TList.getObject: tObject; begin if self.hasAccess then result := current.getContent else result := nil; end;
procedure TList.setObject(pObject: TObject); begin if (pObject <> nil) and self.hasAccess then current.setContent(pObject) end;
procedure TList.insert(pObject: TObject); var currentPos, aktPos, newNode, frontNode:TNode; begin if pObject <> nil then begin if self.isEmpty then self.append(pObject) else begin if self.hasAccess then begin currentPos := current; aktPos := current; newNode := TNode.create(pObject); newNode.setNext(current); if aktPos = first then first := newNode else begin self.toFirst; frontNode := current; while self.hasAccess and (current <> aktPos) do begin frontNode := current; self.next; end; frontNode.setNext(newNode); end; current := currentPos; end; end; end; end;
procedure TList.append(pObject: TObject); var currentPos, newNode, previousNode: TNode; begin if pObject <> nil then begin currentPos := current; newNode := TNode.create(pObject); newNode.setNext(tail); if self.isEmpty then first := newNode else begin previousNode := tail.getNext; previousNode.setNext(newNode); end; tail.setNext(newNode); current := currentPos; end; end;
procedure TList.concat(pList: TList); var currentPos,lastNode,dummy: TNode; begin if (pList <> nil) and not pList.isEmpty then begin if self.isEmpty then begin first := pList.first; tail := pList.tail; current := tail; end else begin currentPos := current; lastNode := tail.getNext; tail := pList.tail; dummy := lastNode.nextNode; lastNode.setNext(pList.first); if currentPos = dummy then current := tail else current := currentPos; dummy.destroy; end; pList.tail := TNode.create(nil); pList.first := pList.tail; pList.tail.setNext(pList.tail); pList.current := pList.first; end; end;
procedure TList.remove; var currentPos, markPos, frontPos: TNode; begin if not self.isEmpty and self.hasAccess then begin currentPos := current; if current = first then begin first := current.getNext; if current.getNext = tail then tail.setNext(first); current := first; end else begin markPos := current; self.toFirst; frontPos := current; while self.hasAccess and (current <> markPos) do begin frontPos := current; self.next; end; frontPos.setNext(markPos.getNext); current := frontPos.getNext; if current = tail then tail.setNext(frontPos); end; currentPos.destroy; end; end;
destructor TList.destroy; begin while not self.isEmpty do begin self.toFirst; self.remove; end; tail.destroy; inherited destroy; end;
end. |
So habe ich mir vorgestellt soll das Programm darauf zugreifen:
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TForm1.Button6Click(Sender: TObject); begin db.destroy; ausgabe; end; |
hier ist die Klasse Fachbuch, die noch nicht angelegt wurde, sondern nur da ist, damit man es in der GUI aufrufen kann
Delphi-Quelltext
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:
| UNIT uTFachbuch;
interface
uses uTBuch;
type TFachbuch = class(TBuch)
protected Kategorie : string;
public constructor create (pAnzahl: integer; pPreis: integer; pAutor: string; pISBN: string; pTitel: string; pKategorie: string); virtual; function GibKategorie : string; virtual;
end;
implementation
constructor TFachbuch.create (pAnzahl: integer; pPreis: integer; pAutor: string; pISBN: string; pTitel: string; pKategorie: string); begin anzahl:=pAnzahl; preis:=pPreis; autor:=pAutor; isbn:=pISBN; titel:=pTitel; kategorie:=pKategorie; end;
function TFachbuch.GibKategorie : string; begin result := Kategorie end;
end. |
und ich weiß nicht ob man das noch zum Verständnis braucht:
Delphi-Quelltext
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:
| UNIT uTBuch;
interface
type TBuch = class(TObject)
protected Anzahl : integer; Preis : integer; Autor : string; ISBN : string; Titel : string;
public procedure create; virtual; procedure SetzeAnzahl (pAnzahl: integer); virtual; function GibAnzahl : integer; virtual; function GibAutor : string; virtual; function GibISBN : string; virtual; function GibPreis : integer; virtual; function GibTitel : string; virtual; destructor destroy; virtual;
end;
implementation
procedure TBuch.create; begin end;
procedure TBuch.SetzeAnzahl (pAnzahl: integer); begin Anzahl := pAnzahl end;
function TBuch.GibAnzahl : integer; begin result := Anzahl end;
function TBuch.GibAutor : string; begin result := Autor end;
function TBuch.GibISBN : string; begin result := ISBN end;
function TBuch.GibPreis : integer; begin result := Preis end;
function TBuch.GibTitel : string; begin result := Titel end;
destructor TBuch.destroy; begin end;
end. |
Ich hoffe, das ist alles richtig so.
LG Fly
Moderiert von
Narses: Topic aus Sonstiges (Delphi) verschoben am Mi 30.05.2012 um 22:26
glotzer - Mi 30.05.12 22:01
Hallo und wilkommen :D
der Fehler ist ganz einfach:
statt destructor destroy;virtual; einfach destructor destroy;override; und alles sollte funktionieren.
FlySource - Mi 30.05.12 22:42
Ja, schön wäre es, wenn das so einfach funktionieren würde, allerdings, behebt es das Problem an sich nicht, denn es kommt wieder eine Zugriffsverletzung wenn man das Programm ausführt, diesen Vorschlag habe ich nämlich auch schon ausprobiert, es ist wahrscheinlich nur eine dumme Kleinigkeit, aber ich komme nicht drauf, den falsch programmiert scheint das destroy nicht zu sein, zumindest nicht in meinen Augen.
MfG
Lemmy - Mi 30.05.12 23:29
FlySource hat folgendes geschrieben : |
denn es kommt wieder eine Zugriffsverletzung wenn man das Programm ausführt |
verrätst Du uns auch wo die Zugriffsverletzung kommt (Stichwort Debugger) oder sollen wir raten? ;-)
Grüße
FlySource - Do 31.05.12 07:02
Ja na klar, also wenn ich das Programm starte, es dann abstürtzt, bleibt es immer bei der procedure buttonclick6 in der büchergui hängen, so wie es aussieht.
Ich hoffe es ist die Information, die gesucht war.
Grüße
jaenicke - Do 31.05.12 07:06
Erstens sollte man immer Objekt.Free oder FreeAndNil(Objekt) verwenden, zweitens ist dir hoffentlich klar, dass du nach db.Destroy auch nicht mehr auf db zugreifen darfst ohne es neu zu erzeugen. (Passiert in ausgabe vielleicht ein Zugriff auf db? ;-))
Bei welcher Zeile kommt denn die Schutzverletzung? Setze doch einfach mal einen Haltepunkt (F5) auf das (dann hoffentlich schon ersetzte ;-)) db.Destroy, starte das Programm und gehe schrittweise durch (F7), wenn das Programm dort ankommt. Wo passiert der Fehler?
FlySource - Do 31.05.12 14:05
So naja ich habe mal durchgeschaut und ja es war das Problem mit der Ausgabe ^^
Naja ich habs jetzt so gemacht, dass die datenbank gelöscht wird, dass muss sie ja, weil auf sie ja nicht mehr zugegriffen werden konnte oder sehe ich das falsch?
Dann habe ich anstatt die Listbox mit der db zu überschreiben, was ja nicht ging einfach auf listbox1.clear gesetzt.
Das angeprochene Objekt.free oder freeandnil hatten wir bisher noch nicht im Unterricht von daher, meide ich meist immer das was wir nicht im Unterricht machen, weil wir ja auch mit den uns bekannten Methoden die Arbeit schreiben.
jaenicke - Do 31.05.12 14:15
FlySource hat folgendes geschrieben : |
Das angeprochene Objekt.free oder freeandnil hatten wir bisher noch nicht im Unterricht von daher, meide ich meist immer das was wir nicht im Unterricht machen, weil wir ja auch mit den uns bekannten Methoden die Arbeit schreiben. |
Du kannst deinem Lehrer ja mal die Hilfe zu Destroy zeigen. ;-)
Das so erst zu lernen ist nicht schön...
FlySource - Do 31.05.12 14:47
Naja was heißt schon lernen, er hat halt gesagt, weil er im Stress war, macht das mal und naja wir haben das halt noch nicht besprochen und morgen schreiben wir halt Klausur, und da wir nicht an ein und derselben Schule Info haben, hab ich ihn heute auch nicht angetroffen...
Hauptsache ist halt, dass es von der Sache her richtig programmiert ist und die Oberfläche ist in der Arbeit meist nicht so wichtig, weil die aufm papier eh schwer darzustellen ist, dann muss man noch mehr aufpassen, wo man was hat ^^
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!