Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Fehler mit Pointern
ShadeMoon - Di 02.06.09 12:53
Titel: Fehler mit Pointern
Ich bin gerade dabei, für die Schule eine kleine Datenbank zu schreiben. Leider funktioniert eine Methode nicht so, wie sie sollte. Ich habe bestimmt eine halbe Stunde lang versucht, herauszufinden, woran es liegt. So langsam glaube ich schon, es handelt sich um einen Bug in Delphi.
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:
| unit SaveStructs;
interface
uses SysUtils;
type
Integers = array of Integer;
PPartner = ^TPartner; TPartner = record Name, Vorname: string; Klasse: string;
Sponsoring: string; Praktikumsplatz: Boolean;
Nachhilfe: record Fach: string; StundenProWoche: Byte; end;
Unterstuetzung: record Schulfest: Boolean; Klassenfahrt: Boolean; Unterrichtsbeitrag: Boolean; EDV: Boolean; end;
Organisation: Byte; Bibliotheksaufsicht: Byte; Suchtberatung: Byte; Rechtskunde: Byte; Handwerk: string;
ExperteFuer: string;
Sonstiges: string; end;
PListElm = ^TListElm; TListElm = record Partner: PPartner; Next: PListElm; end;
TPartnerList = class private First: PListElm; Curr: PListElm; CurrID: Integer; public procedure Add(const Partner: TPartner); end;
implementation
procedure TPartnerList.Add(const Partner: TPartner); var AddAfter, AddBefore: PListElm; New: PListElm; begin GetMem(New, SizeOf(TListElm)); GetMem(New^.Partner, SizeOf(TPartner)); New^.Partner^ := Partner;
if First <> nil then begin AddAfter := First; AddBefore := AddAfter^.Next; while (AddBefore <> nil) and Priority(AddBefore^.Partner^, Partner) do begin AddAfter := AddBefore; AddBefore := AddBefore^.Next; end; New^.Next := AddBefore; AddAfter^.Next := New; end else begin New^.Next := nil; First := New; end; end;
end. |
Wenn die Methode Add aufgerufen wird, tritt in der dritten Zeile (Zeile 74 des Codes) der Methode ein Fehler wegen Zugriffsverletzung auf.
Die Variable New^.Partner^ soll zu diesem Zeitpunkt undefiniert sein. Mit Ausnahme von
Name und
Vorname sind aber alle ihre Elemente definiert. Ich frage mich, wie das gehen soll.
Ich programmiere jetzt schon seit einigen Jahren mit Delphi, aber so etwas ist mir noch nicht begegnet.
Würde mich freuen, wenn jemand Rat weiß.
Moderiert von
Narses: Code- durch Delphi-Tags ersetzt
Sinspin - Di 02.06.09 16:02
Hi und :welcome: in der EE.
Einen Fehler in Delphi kann ich schonmal ausschließen, denke ich, auch wenn ich so adhoc auch keinen Fehler in deinem Quelltext sehe. Aber du könntest mal noch ein paar Sachen ausprobieren, falls du das noch nicht gemacht hast.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TPartnerList.Add(const Partner: TPartner); var AddAfter, AddBefore: PListElm; NewEntry: PListElm; NewPartner: PPartner;
begin GetMem(NewEntry, SizeOf(TListElm)); GetMem(NewPartner, SizeOf(TPartner)); NewPartner^ := Partner; NewEntry^.Partner := NewPartner; end; |
Das was du geschrieben hast klingt auf jeden Fall danach als wenn du dir Speicher überschrieben hättest.
Versuch es mal mit meinen Änderungen und berichte.
Delete - Di 02.06.09 16:14
Und der Variablenname New ist unglücklich gewählt.
ShadeMoon - Di 02.06.09 16:25
Danke!
Hm, ich verwende aus Prinzip GetMem statt New. Also, ursprünglich war der Grund, dass ich von New erst erfahren habe, als sich mein Informatiklehrer gewundert hat, was denn GetMem sei.^^ Und nun habe ich mich halt daran gewöhnt.
Ich habe die Variable jetzt mal umbenannt, aber der Fehler besteht, wie erwartet, leider weiterhin.
Sinspin - Di 02.06.09 16:36
Hast du auch die anderen Sachen geändert die ich dir vorgeschlagen habe?
AndyB - Di 02.06.09 17:59
ShadeMoon hat folgendes geschrieben : |
| Hm, ich verwende aus Prinzip GetMem statt New. |
Und darin liegt wohl der Fehler. New() ruft zusätzlich noch InitializeRecord auf, das die String-Felder initialisiert. Auch Dispose() ruft im Gegensatz zu FreeMem auch noch FinalizeRecord auf, dass die String-Felder wieder aufräumt.
Moderiert von
Narses: Zitat repariert
ShadeMoon - Mo 08.06.09 07:11
Danke für die Hilfe, auch wenn ich den Fehler damit auch nicht beheben konnte, denn ich hatte vor lauter Pointern ganz vergessen, die Klasse zu instantiïeren.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!