Autor Beitrag
ShadeMoon
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 02.06.09 13:53 
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.
ausblenden volle Höhe 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;// in Stunden pro Woche
  Bibliotheksaufsicht: Byte; // in Stunden pro Woche
  Suchtberatung: Byte; // in Stunden je Woche
  Rechtskunde: Byte; // in Stunden je Woche

  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;
{FEHLER in vorheriger Zeile:
  […]
  Exception der Klasse EAccessViolation […]
  Zugriffverletzung bei Adresse […]
  Lesen von Adresse 0000002C […]
}

  if First <> nil then
  begin
    AddAfter := First;
    AddBefore := AddAfter^.Next;
    while (AddBefore <> niland 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 user profile iconNarses: Code- durch Delphi-Tags ersetzt
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Di 02.06.09 17: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.
ausblenden 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; // New ist eine Procedure
  NewPartner: PPartner; 

begin
  GetMem(NewEntry, SizeOf(TListElm));
  GetMem(NewPartner, SizeOf(TPartner)); // Zeiger auf TPartner erstmal in eigener Variable erstellen
  NewPartner^ := Partner; // inhalt der variable in den speicherbereich kopieren
  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.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 02.06.09 17:14 
Und der Variablenname New ist unglücklich gewählt.
ShadeMoon Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Di 02.06.09 17: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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Di 02.06.09 17:36 
Hast du auch die anderen Sachen geändert die ich dir vorgeschlagen habe?

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Di 02.06.09 18:59 
user profile iconShadeMoon hat folgendes geschrieben Zum zitierten Posting springen:
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 user profile iconNarses: Zitat repariert

_________________
Ist Zeit wirklich Geld?
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1335
Erhaltene Danke: 118

Win 10
RIO, CE, Lazarus
BeitragVerfasst: Di 02.06.09 22:50 
user profile iconAndyB hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconShadeMoon hat folgendes geschrieben Zum zitierten Posting springen:
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.

Oh ja, daran habe ich garnicht gedacht! Lange Strings und dynamische Arrays kannst du, soweit ich weis, nicht ohne Probleme verwenden wenn du mit selbst reserviertem Speicher arbeitest. Pass mal deine Records so an das du statt String überall ShortString verwendest, das ist zwar erstmal Speicherverschwendung, aber wenn der Fehler dann weg ist weißt du woran es lag.

_________________
Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
ShadeMoon Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 08.06.09 08: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.