Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - [Anfänger] Beispielprogramm mit Pointer bringt Runtime error


IchLerneSchnell - Fr 02.03.12 19:05
Titel: [Anfänger] Beispielprogramm mit Pointer bringt Runtime error
Hallo zusammen.

Ich bin gerade dabei, Delphi zu lernen und bis jetzt läuft es auch recht gut. Erste Programme wie eine Konsolenversion für Conways Spiel des Lebens sind mir nach anfänglichen Schwierigkeiten gelungen. Jetzt habe ich begonnen, mich mit Pointern auseinanderzusetzen und dazu ein Tutorial gefunden und daraus dieses Beispielprogramm:


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:
PROGRAM pointer;

  TYPE link  = ^liste;
       liste = RECORD
                 name : STRING [80];
                 next : link;
               END;

  VAR p,first : link;
      index   : integer;
      n       : STRING [80];

BEGIN
  (* Das später letzte Element der Liste zeigt auf *)
  (* keinen weiteren Datensatz. *)
    first := NIL;

  FOR index := 1 TO 10 DO
  BEGIN
    (* Pointerelemente einlesen *)
      write ('->');
      readln (n);
    (* Anfordern eines neuen Records *)
      new (p);
    (* Zuweisen des Recorddatenfeldes *)
      p^.name := n;
    (* Der neue Record bekommt die Adresse des *) (* letzten Records, die ja in "first" noch *)
    (* steht. *)
      p^.next := first;
    (* Aktualisieren des Anfangszeigers *)
      first := p
  END;
  (* Vorbereitung der Ausgabe: Zeiger "p" wird auf *)
  (* das "erste" Element der Liste gesetzt *)
    p := first;
  WHILE (p <> NILDO
  BEGIN
    (* Pointerelemente ausgeben *)
      write (p^.name);
    (* Setzen des Zeigers auf den nächsten Record *)
      p := p^.next
  END
END.


Mein Problem ist jetzt, dass mir Delphi (Turbo Delphi) einen Runtime error gibt, wenn ich versuche das Programm laufen zu lassen. Ich sehe nur nicht ein, wo das Problem ist. Muss ich die reservierten Speicherbereiche wieder freigeben?

Vielen Dank für eure Hilfe.

freundliche Grüße.

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt


Martok - Fr 02.03.12 19:26

Hallo und :welcome:!

user profile iconIchLerneSchnell hat folgendes geschrieben Zum zitierten Posting springen:
Mein Problem ist jetzt, dass mir Delphi (Turbo Delphi) einen Runtime error gibt, wenn ich versuche das Programm laufen zu lassen. Ich sehe nur nicht ein, wo das Problem ist.
Was du nicht verraten hast: was für einen? Ich tippe mal auf EA-Fehler 105.

Um in Delphi eine Konsolenanwendung zu erstellen (und nur dann kannst du WriteLn etc benutzen) musst du das direkt ansagen.
Füge also ganz am Anfang des Programms (genaugenommen spielt das keine Rolle, aber es ist übersichtlicher) folgendes ein:
{$APPTYPE CONSOLE}Damit weiß Delphi, dass es jetzt eine Konsole initialisieren muss.

user profile iconIchLerneSchnell hat folgendes geschrieben Zum zitierten Posting springen:
Muss ich die reservierten Speicherbereiche wieder freigeben?
Da du grade lernst die grundsätzliche Antwort: ja, immer!
Hier ist es nicht zwingend notwendig, da alles reservierte eh freigegeben wird, wenn das Programm beendet wird. Aber wenn das Programm mal nicht direkt danach beendet wird, hast du da ein schönes Speicherleck.


IchLerneSchnell - Fr 02.03.12 19:35

Hallo wieder.

Genau der Konsolenmodus hat gefehlt. Genau das selbe Problem hatte ich bei Conways Spiel des Lebens, hatte ich ganz vergessen... Vielen Dank.

freundliche Grüße. :)

Edit: Wenn der Thread schon offen ist, hätte ich noch eine Frage zu dem Beispielcode. Verstehe ich das richtig, dass ich als Endergebnis einen großen String habe und nicht mehr auf die einzelnen Angaben als seperate Teile zugreifen kann?

Edit2: Habe das Beispiel jetzt verstanden.


Delphi-Laie - Fr 02.03.12 22:56

Es wundert mich, daß der Compiler so klaglos write, writeln, read und readln ohne diesen Compilerbefehl {$APPTYPE CONSOLE} schluckt, den Quelltext also ohne Beanstandung compiliert. Oder kamen wenigstens Hinweise oder Warnungen? Falls nein, nehme ich nicht an, daß {$WARNINGS OFF} der Grund war (ist im obigen - hoffentlich vollständigen - Quelltext ja auch nicht enthalten).


jaenicke - Fr 02.03.12 23:47

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Es wundert mich, daß der Compiler so klaglos write, writeln, read und readln ohne diesen Compilerbefehl {$APPTYPE CONSOLE} schluckt, den Quelltext also ohne Beanstandung compiliert.
Der Compiler kann auch nicht wissen, dass das nicht korrekt ist. Du kannst auch problemlos in einer VCL-Anwendung zusätzlich eine Konsole erstellen und dann auch mit diesen Befehlen arbeiten. Du musst eben nur die Konsole manuell initialisieren und deinitialisieren. Und ob du das irgendwo machst, kann der Compiler nicht prüfen.