Forum: PC-Programmierung Hilfe zu C-Programm


von F.Keilbach (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bin gerade dabei eine verkettete Liste mit C zu realisieren.
Die Funktion einfügen funktion ohne Probleme. Nur wenn ich die
Funktion
ausgabe ausführe stürtz mein Programm ab! Wo kann da der Fehler sein?

von F.Keilbach (Gast)


Angehängte Dateien:

Lesenswert?

Fehlermeldung siehe Anhang!

von Hans (Gast)


Lesenswert?

bei sowas würd ich sagen access violation...

 hzgr ->text1 = (char*)malloc(sizeof(struct telement));
  hzgr ->text2 = (char*)malloc(sizeof(struct telement));

das schaut mir nicht richtig aus.. du kopierst 100bytes drüber aber
telement hat sicher keine 100bytes.. probier hier mal ein
malloc(strlen(a)+1) bzw malloc(strlen(b)+1) aus...

sonnst endwanz das mal.. es kracht garantiert beim einhängen wenn ich
das richtig sehe...

73

von Rolf Magnus (Gast)


Lesenswert?

@Hans:

beim einhängen?
Meinten Sie: beim anhängen?

@F.Keilbach:

> ich bin gerade dabei eine verkettete Liste mit C zu realisieren.

Warum hat dein Sourcefile dann die Endung .cpp? Die ist eher für
C++-Programme üblich, und einige Compiler werden bei dieser Endung
automatisch in den C++-Modus umschalten.

> Die Funktion einfügen funktion ohne Probleme. Nur wenn ich die
> Funktion ausgabe ausführe stürtz mein Programm ab! Wo kann da der
> Fehler sein?

Ich denke auch, daß es daran liegt, daß du für die Strings die falsche
Größe allokierst. Was sollte sizeof(struct telement) mit der Länge der
Strings zu tun haben?

Hier noch ein paar andere Sachen, die mir aufgefallen sind:

Lasse die Casts bei malloc weg. Die bringen keinen Vorteil, können aber
machmal einen Fehler verdecken. Wenn dein Compiler meckert -> Als C
compilieren.

In loeschen wird nur der Speicher des telement-Objekts gelöscht, nicht
der der beiden Strings.

Warum wird in main anker->zeiger die Adresse von anker selbst
zugewiesen? Dadurch wird die Liste zum Ring und damit endlos.

von F.Keilbach (Gast)


Lesenswert?

Ja was muss ich da tun damit die Fehlermeldung nicht auftaucht? ich bin
jetzt total verwirrt.

void einfuegen( struct telement *z, char *a, char *b )
 {
  struct telement *hzgr;
  hzgr = (struct telement*)malloc(sizeof(struct telement));
  hzgr ->text1 = (char*)malloc(strlen(hzgr ->text1));
  hzgr ->text2 = (char*)malloc(strlen(hzgr ->text2));
  strcpy(hzgr->text1,a);
  strcpy(hzgr->text2,b);
  hzgr->zeiger=z->zeiger;
  z->zeiger = hzgr;
  return;
 }

Die Funktion habe ich jetzt mal zu abgeändert.

von F.Keilbach (Gast)


Lesenswert?

Funzt aber immer noch nicht!!

von Karl heinz B. (heinzi)


Lesenswert?

Du legst mit

  anker = (struct telement*)malloc( sizeof(struct telement)) ;
  anker->zeiger=anker;

einen ersten Eintrag in main an.
Nun wird aber nirgends anker->text1 bzw. anker->text2
auf was vernuenftiges gesetzt. Irgendwann kommt es in
der ausgabe() Funktion dazu, dass printf versucht genau
diese Werte auszugeben. Da die Zeiger aber ins Nirwana
zeigen ...

Eine Methode (und nicht die schlechteste) ist es bei
solchen Sachen mitzuzeichnen. Also: Papier und Bleistift
raus. Wenn Dein Program eine Variable anlegt, dann
malst Du ein Rechteck aufs Papier und schreibst den Namen der
Variablen links oben ueber das Rechteck. Wenn Dein Program
mittels malloc etwas anlegt, dann machst Du genau das gleiche
nur halt ohne Namen. Pointer werden durch Pfeile symbolisiert,
die von einem Rechteck ausgehen und zu einem anderen Rechteck fuehren.
Wichtig: Wenn Dein Program etwas loescht, dann darfst Du auch nur
die Dinge am Papier ausfuehren, die Dein Program auch wirklich
macht. Also: Das Rechteck wird zwar (mit einem Radiergummi)
ausradiert, aber alle Pfeile bleiben so wie sie sind.
Wann immer du auf eine Operation stoesst, die einen Pfeil
benutzt der ins Leere zeigt, hast Du einen ungueltigen Pointer
gefunden. Wenn Dein Programcode sir sagt, dass ein Pointer
ausgewertet werden soll, aber auf Deinem Papier kein Pfeil da
ist, dann hast Du einen uninitialisierten Pointer gefunden.
Ansonsten schreibst Du immer alle Wert zb. bei einer Zuweisung
in das zugehoerige Rechteck, bzw. im Falle eines Pointers werden
ganz einfach Pfeile gezogen.

(Weiterlesen im nachsten Posting)

von Karl heinz B. (heinzi)


Lesenswert?

Konkret:
Dein Program faengt in main an. Ich spar mir jetzt
das ganze Gesocks mit den Puffern und postuliere dass
die scanf durchgelaufen sind und die "Test1" und "abcd"
eingegeben hast:

  anker
  +--------+
  |        |
  +--------+

  puffer1
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | T | e | s | t | 1 | \0|   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+

  puffer2
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | a | b | c | d | \0|   |   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+


Das ist die Ausgangssituation, hier gehts weiter

anker = (struct telement*)malloc( sizeof(struct telement)) ;


 malloc erzeugt ein neues Objekt, in diesem Fall eine Struktur. Also:


  anker
  +--------+
  |        |
  +--------+



                  +----------------+
                  | text1 :        |
                  | text2 :        |
                  | zeiger:        |
                  +----------------+


  puffer1
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | T | e | s | t | 1 | \0|   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+

  puffer2
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | a | b | c | d | \0|   |   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+

 ... und die Zuweisung sorgt dafuer, dass die Adresse, die
 von malloc zurueckgegeben wird in anker gespeichert wird.
 Wir sagen auch: anker zeigt auf das neue Objekt. Auf Deinem
 Papier sieht das dann so aus:


  anker
  +--------+
  |    o--------+
  +--------+    |
                |
                |
                |
                | +----------------+
                +>| text1 :        |
                  | text2 :        |
                  | zeiger:        |
                  +----------------+


  puffer1
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | T | e | s | t | 1 | \0|   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+

  puffer2
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | a | b | c | d | \0|   |   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+

(Weiter im naechsten Posting)

von Karl heinz B. (heinzi)


Lesenswert?

Naechste Anweisung:

  anker->zeiger=anker;

fangen wir mit der linken Seite der Zuweisung an.

  anker->zeiger

Such mal das Rechteck, dass mit 'anker' bezeichnet ist.
Dann kommt der '->'. In Deiner Zeichnung muss also von
diesem Rechteck ein Pfeil ausgehen. Tut er auch. Folge
dem Pfeil.
  anker->zeiger
In dem Rechteck auf das dieser Pfeil zeigt, siche das Feld
zeiger.
Hast Du's? Gut.

Soweit der linke Teil der Zuweisung. Merk Dir das Feld, das
bekommt gleich einen neuen Wert.
Welchen?

  anker->zeiger=anker;

Also 'anker'. Da 'anker' ein Pointer ist, ist der neue Wert
also ein Pfeil, der auf dasselbe Objekt zeigt wie 'anker'.
Trage den in die Zeichnung ein:

  anker
  +--------+
  |    o--------+
  +--------+    |
                |
                |
                |
                | +----------------+
                +>| text1 :        |
                  | text2 :        |
            +---->| zeiger:  o-----------+
            |     +----------------+     |
            |                            |
            |                            |
            +----------------------------+



  puffer1
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | T | e | s | t | 1 | \0|   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+

  puffer2
  +---+---+---+---+---+---+---+--- ... ---+---+---+
  | a | b | c | d | \0|   |   |           |   |   |
  +---+---+---+---+---+---+---+--- ... ---+---+---+

Damit ist die Zuweisung abgeschlossen (und man sieht
auch sehr deutlich, dass text1 und text2 auf nichts
spezielles zeigen).

Naechste Anweisung:

einfuegen(anker,puffer1,puffer2);

Also ein Funktionsaufruf. Dn musst Du im Kopf machen
und Dir merken wo der Aufruf erfolgt ist (fuer den
Ruecksprung). Ansonsten ist nicht viel zu tun:
Fuer die Parameter werden neue Variablen erzeugt
und mit den Argumenten initialisiert:

void einfuegen( struct telement *z, char *a, char *b )

Es gibt also ein z, ein a und ein b, und als Werte bekommern
sie:
  z - zeigt dorthin, wohin auch anker zeigt
  a - zeigt auf den Anfang von puffer1
  b - zeigt auf den Anfang von puffer2



  anker
  +--------+
  |    o--------+
  +--------+    |
                |
                |
                |
                | +----------------+
                +>| text1 :        |
     +----------->| text2 :        |
     |      +---->| zeiger:  o-----------+
     |      |     +----------------+     |
     |      |                            |
     |      |                            |
     |      +----------------------------+
     |
     |
  z  |      a        b
  +--|-+    +----+   +----+
  |  o |    | o  |   |  o |
  +----+    +-|--+   +--|-+
              |         |
              |         |
+-------------+         |
|                       |
|  +--------------------+
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+

und los gehts in einfuegen
Die erste Aktion ist wieder einfach zu machen:

 struct telement *hzgr;

Eine zusaetzliche lokale Variable wird erzeugt:

  anker
  +--------+
  |    o--------+
  +--------+    |
                |
                |
                |
                | +----------------+
                +>| text1 :        |
     +----------->| text2 :        |
     |      +---->| zeiger:  o-----------+
     |      |     +----------------+     |
     |      |                            |
     |      |                            |
     |      +----------------------------+
     |
     |
  z  |      a        b              hzgr
  +--|-+    +----+   +----+         +------+
  |  o |    | o  |   |  o |         |      |
  +----+    +-|--+   +--|-+         +------+
              |         |
              |         |
+-------------+         |
|                       |
|  +--------------------+
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+


Man beachte: Die Variable ist nicht initialisert worden, daher
ist das Rechteck auch leer.

(Weiter im naechsten Posting)

von Karl heinz B. (heinzi)


Lesenswert?

hzgr = (struct telement*)malloc(sizeof(struct telement));

Das ist wieder leicht. Ein neues Rechteck fuer malloc( ... ) erzeugen
und hzgr darauf zeigen lassen:

  anker
  +--------+
  |    o--------+
  +--------+    |                       +---------------+
                |                    +->| text1:        |
                |                    |  | text2:        |
                |                    |  | zeiger:       |
                | +----------------+ |  +---------------+
                +>| text1 :        | +---+
     +----------->| text2 :        |     |
     |      +---->| zeiger:  o--------+  |
     |      |     +----------------+  |  |
     |      |                         |  |
     |      |                         |  |
     |      +-------------------------+  |
     |                                   |
     |                                   |
  z  |      a        b              hzgr |
  +--|-+    +----+   +----+         +----|-+
  |  o |    | o  |   |  o |         |    o |
  +----+    +-|--+   +--|-+         +------+
              |         |
              |         |
+-------------+         |
|                       |
|  +--------------------+
|  |
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+

  hzgr ->text1 = (char*)malloc(sizeof(struct telement));
  hzgr ->text2 = (char*)malloc(sizeof(struct telement));

Die mallocs erzeugen wieder neue Rechtecke. Es muessen Pfeile
von hzgr->text1 nzw. hzgr->text2 zu diesen Rechtecken installiert
werden:

  anker
  +--------+
  |    o--------+
  +--------+    |                       +---------------+
                |                    +->| text1:   o-------+
                |                    |  | text2:   o------+|
                |                    |  | zeiger:       | ||
                | +----------------+ |  +---------------+ ||
                +>| text1 :        | +---+                ||
     +----------->| text2 :        |     |     +----------+|
     |      +---->| zeiger:  o--------+  |     |           |
     |      |     +----------------+  |  |     |           |
     |      |                         |  |     v           |
     |      |                         |  |    +----------+ |
     |      +-------------------------+  |    | text1:   | |
     |                                   |    | text2:   | |
     |                                   |    | zeiger:  | |
  z  |      a        b              hzgr |    +----------+ |
  +--|-+    +----+   +----+         +----|-+               |
  |  o |    | o  |   |  o |         |    o |  +------------+
  +----+    +-|--+   +--|-+         +------+  |
              |         |                     v
              |         |                   +-----------+
+-------------+         |                   | text1:    |
|                       |                   | text2:    |
|  +--------------------+                   | zeiger:   |
|  |                                        +-----------+
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+


strcpy( hzgr->text1, a );

ok.
hzgr         Suche das Feld namens 'hzgr'
hzgr->       Dort muss es einen Pfeil geben. Folge ihm
hzgr->text1  Im Rechteck in dem du gelandet bist, suche das
             Feld 'text1'

a            Der ist leicht. Einfach 'a' suchen.

So und jetzt kommt der strcpy. Von dem wissen wir, dass er
beide Argumente als Pointer auffasst. D.h. Im obigen mussen
beide Argumente POinter sein, d.h von ihnen muessen Pfeile
ausgehen:
  hzgr->text1   passt, da geht ein Pfeil weg
  a             passt auch, da geht auch ein Pfeil weg.

Obwohl, so ganz passt das nicht.
a zeigt auf ein Array von Charactern. Diese sind auch '\0'
terminiert. Aber hzgr->text1 tut das nicht. Der Pfeil der
dort weggeht zeigt auf eine telement Datenstruktur und
kein Character Array. Also korrigieren wir das mal ganz schnell:
Anstatt

  hzgr ->text1 = (char*)malloc(sizeof(struct telement));
  hzgr ->text2 = (char*)malloc(sizeof(struct telement));

kommt:

  hzgr ->text1 = malloc( strlen( a ) + 1 );
  hzgr ->text2 = malloc( strlen( b ) + 1 );

So. Damit ist jeweils genuegend Speicher allokiert, damit
die Texte auch kopiert werden koennen:


  anker
  +--------+
  |    o--------+
  +--------+    |                       +---------------+
                |                    +->| text1:  o--------+
                |                    |  | text2:  o-------+|
                |                    |  | zeiger:       | ||
                | +----------------+ |  +---------------+ ||
                +>| text1 :        | +---+                ||
     +----------->| text2 :        |     |                ||
     |      +---->| zeiger:  o--------+  |     +-----------+
     |      |     +----------------+  |  |     |          |
     |      |                         |  |     |          |
     |      |                         |  |     |          |
     |      +-------------------------+  |     |          |
     |                                   |     |          |
     |                                   |     |          |
  z  |      a        b              hzgr |     |          |
  +--|-+    +----+   +----+         +----|-+   |          |
  |  o |    | o  |   |  o |         |    o |   |          |
  +----+    +-|--+   +--|-+         +------+   |          |
              |         |                      |          |
              |         |    +-----------------+          |
+-------------+         |    | +---+---+---+---+---+---+  |
|                       |    +>|   |   |   |   |   |   |  |
|  +--------------------+      +---+---+---+---+---+---+  |
|  |                        +-----------------------------+
|  |                        |  +---+---+---+---+---+
|  |                        +->|   |   |   |   |   |
|  |                           +---+---+---+---+---+
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+


Jetzt koennen die strcpy loslegen:

  strcpy(hzgr->text1,a);
  strcpy(hzgr->text2,b);

  anker
  +--------+
  |    o--------+
  +--------+    |                       +---------------+
                |                    +->| text1:  o--------+
                |                    |  | text2:  o-------+|
                |                    |  | zeiger:       | ||
                | +----------------+ |  +---------------+ ||
                +>| text1 :        | +---+                ||
     +----------->| text2 :        |     |                ||
     |      +---->| zeiger:  o--------+  |     +-----------+
     |      |     +----------------+  |  |     |          |
     |      |                         |  |     |          |
     |      |                         |  |     |          |
     |      +-------------------------+  |     |          |
     |                                   |     |          |
     |                                   |     |          |
  z  |      a        b              hzgr |     |          |
  +--|-+    +----+   +----+         +----|-+   |          |
  |  o |    | o  |   |  o |         |    o |   |          |
  +----+    +-|--+   +--|-+         +------+   |          |
              |         |                      |          |
              |         |    +-----------------+          |
+-------------+         |    | +---+---+---+---+---+---+  |
|                       |    +>| T | e | s | t | 1 | \0|  |
|  +--------------------+      +---+---+---+---+---+---+  |
|  |                        +-----------------------------+
|  |                        |  +---+---+---+---+---+
|  |                        +->| a | b | c | d | \0|
|  |                           +---+---+---+---+---+
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+

Naechste Anweisung:

hzgr->zeiger=z->zeiger;

 hzgr                 Suche das Feld 'hzgr'
 hzgr->               folge dem Pfeil
 hzgr->zeiger         Im Rechteck suche das Feld 'zeiger'
                      Dort muss ein neuer Wert hin

 z                    Suche das Rechteck z
 z->                  Folge dem Pfeil
 z->zeiger            und dort wieder das Feld zeiger

 Arrangiere die Dinge so, dass hzgr->zeiger einen Pfeil
 bekommt, der auf das gleiche zeigt wie z->zeiger:

  anker
  +--------+
  |    o--------+
  +--------+    |                       +---------------+
                |                    +->| text1:  o--------+
                |  +----------------+|  | text2:  o-------+|
                |  v                ||  | zeiger: o     | ||
                | +----------------+||  +---------|-----+ ||
                +>| text1 :        ||+---+        |       ||
     +----------->| text2 :        |+-------------+       ||
     |      +---->| zeiger:  o--------+  |     +-----------+
     |      |     +----------------+  |  |     |          |
     |      |                         |  |     |          |
     |      |                         |  |     |          |
     |      +-------------------------+  |     |          |
     |                                   |     |          |
     |                                   |     |          |
  z  |      a        b              hzgr |     |          |
  +--|-+    +----+   +----+         +----|-+   |          |
  |  o |    | o  |   |  o |         |    o |   |          |
  +----+    +-|--+   +--|-+         +------+   |          |
              |         |                      |          |
              |         |    +-----------------+          |
+-------------+         |    | +---+---+---+---+---+---+  |
|                       |    +>| T | e | s | t | 1 | \0|  |
|  +--------------------+      +---+---+---+---+---+---+  |
|  |                        +-----------------------------+
|  |                        |  +---+---+---+---+---+
|  |                        +->| a | b | c | d | \0|
|  |                           +---+---+---+---+---+
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+

(Weiter im naechsten Posting)

von Karl heinz B. (heinzi)


Lesenswert?

z->zeiger = hzgr;

  und zu guter letzt soll auch z->zeiger noch einen
  neuen Pfeil bekommen: Der soll dorthin zeigen wo auch
  hzgr hinzeigt:


  anker
  +--------+                     +--------+
  |    o--------+                |        v
  +--------+    |                |      +---------------+
                |                |   +->| text1:  o--------+
                |  +-------------|--+|  | text2:  o-------+|
                |  v             |  ||  | zeiger: o     | ||
                | +------------+ |  ||  +---------|-----+ ||
                +>| text1 :    | |  |+---+        |       ||
     +----------->| text2 :    | |  +-------------+       ||
     |            | zeiger:  o---+       |     +-----------+
     |            +------------+         |     |          |
     |                                   |     |          |
     |                                   |     |          |
     |                                   |     |          |
     |                                   |     |          |
     |                                   |     |          |
  z  |      a        b              hzgr |     |          |
  +--|-+    +----+   +----+         +----|-+   |          |
  |  o |    | o  |   |  o |         |    o |   |          |
  +----+    +-|--+   +--|-+         +------+   |          |
              |         |                      |          |
              |         |    +-----------------+          |
+-------------+         |    | +---+---+---+---+---+---+  |
|                       |    +>| T | e | s | t | 1 | \0|  |
|  +--------------------+      +---+---+---+---+---+---+  |
|  |                        +-----------------------------+
|  |                        |  +---+---+---+---+---+
|  |                        +->| a | b | c | d | \0|
|  |                           +---+---+---+---+---+
|  |
|  |  puffer1
|  |  +---+---+---+---+---+---+---+--- ... ---+---+---+
+--|->| T | e | s | t | 1 | \0|   |           |   |   |
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   |
   |
   |  puffer2
   |  +---+---+---+---+---+---+---+--- ... ---+---+---+
   +->| a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+


Das wars. Dir Funktion ist zuende und alle lokalen Variablen
sowie alle Argument koennen geloescht werden:

  anker
  +--------+                     +--------+
  |    o--------+                |        v
  +--------+    |                |      +---------------+
                |                |      | text1:  o--------+
                |  +-------------|--+   | text2:  o-------+|
                |  v             |  |   | zeiger: o     | ||
                | +------------+ |  |   +---------|-----+ ||
                +>| text1 :    | |  |             |       ||
                  | text2 :    | |  +-------------+       ||
                  | zeiger:  o---+             +-----------+
                  +------------+               |          |
                                               |          |
                                               |          |
                                               |          |
                                               |          |
     |                                         |          |
                                               |          |
                                               |          |
                                               |          |
                                               |          |
                                               |          |
                             +-----------------+          |
                             | +---+---+---+---+---+---+  |
                             +>| T | e | s | t | 1 | \0|  |
                               +---+---+---+---+---+---+  |
                            +-----------------------------+
                            |  +---+---+---+---+---+
                            +->| a | b | c | d | \0|
                               +---+---+---+---+---+

      puffer1
      +---+---+---+---+---+---+---+--- ... ---+---+---+
      | T | e | s | t | 1 | \0|   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+


      puffer2
      +---+---+---+---+---+---+---+--- ... ---+---+---+
      | a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+

Weiter gehts in main

  ausgabe();

Also, dann rufen wir mal diese Funktion auf. Argumente gibts
keine, also koennen wir gleich mal die lokalen Variablen
anlegen:

struct telement *hzgr;

hzgr = anker;

Also: neues Rechteck anlegen und auf das gleiche Rechteck zeigen
lassen wie anker:


  anker
  +--------+                     +--------+
  |    o--------+                |        v
  +--------+    |                |      +---------------+
                |                |      | text1:  o--------+
                |  +-------------|--+   | text2:  o-------+|
                |  v             |  |   | zeiger: o     | ||
                | +------------+ |  |   +---------|-----+ ||
                +>| text1 :    | |  |             |       ||
          +------>| text2 :    | |  +-------------+       ||
          |       | zeiger:  o---+             +-----------+
          |       +------------+               |          |
          |                                    |          |
          +----+                               |          |
               |                               |          |
      hzgr     |                               |          |
      +---+    |                               |          |
      | o------+                               |          |
      +---+                                    |          |
                                               |          |
                                               |          |
                                               |          |
                             +-----------------+          |
                             | +---+---+---+---+---+---+  |
                             +>| T | e | s | t | 1 | \0|  |
                               +---+---+---+---+---+---+  |
                            +-----------------------------+
                            |  +---+---+---+---+---+
                            +->| a | b | c | d | \0|
                               +---+---+---+---+---+

      puffer1
      +---+---+---+---+---+---+---+--- ... ---+---+---+
      | T | e | s | t | 1 | \0|   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+


      puffer2
      +---+---+---+---+---+---+---+--- ... ---+---+---+
      | a | b | c | d | \0|   |   |           |   |   |
      +---+---+---+---+---+---+---+--- ... ---+---+---+

 do

 Da brauchen wir nichts mitzeichnen

printf ("Inhalt Text1: %s", hzgr->text1);

printf soll einen Text ausgeben. %s sorgt
dafuer, indem wir ihm einen Pointer (einen Pfeil)
geben, der an den Anfang des Textes zeigt.
Welches Textes?
hzgr->text1

  hzgr                 hzgr  aufsuchen
  hzgr->               dem Pfeil folgen
  hzgr->text1          das text1 Feld aufsuchen

  In diesem letzten Feld muss ein Pfeil weggehen
  (%s will ja einen). Aber da ist keiner.

      K A B O O M   !!!!



Da hast Du Deinen Absturz

von Karl heinz B. (heinzi)


Lesenswert?

Ja was muss ich da tun damit die Fehlermeldung nicht auftaucht? ich bin
> jetzt total verwirrt.
>
> void einfuegen( struct telement *z, char *a, char *b )
>  {
>   struct telement *hzgr;
>   hzgr = (struct telement*)malloc(sizeof(struct telement));
>   hzgr ->text1 = (char*)malloc(strlen(hzgr ->text1));
>   hzgr ->text2 = (char*)malloc(strlen(hzgr ->text2));

Also, wenn Dir das Schwierigkeiten macht, solltest Du die
Finger von linearen Listen lassen. Du bist noch nicht soweit.

Hinweis: Was gibt strlen zurueck?
Wieviel Speicher braucht der String wirklich

Hinweis 2: C strings sind immer mit einem '\0' terminiert.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

@Karl-Heinz
Langeweile? Ist ja irre. Wie lange hast du denn an den Postings
gearbeitet?

Matthias

von Karl heinz B. (heinzi)


Lesenswert?

@F

>   hzgr ->text1 = (char*)malloc(strlen(hzgr ->text1));

Und warum versuchst Du die Menge des zu allokierenden Speichers
von hzgr->text1 abzulesen. hzgr->text1 enthaelt noch keinen
String. Dafuer allokierst Du doch erst Speicher. 'a' ist
ein Pointer auf den String!

@Matthias

ne gute Stunde.
Da haettest Du erst mal meine Postings in comp.lang.c++ sehen
sollen. Das selbe, nur ausfuehrlicher und in Englisch.

von sackgesicht (Gast)


Lesenswert?

@Karl Heinz

RESPEKT!!!

von Karl heinz B. (heinzi)


Lesenswert?

Ist verstaendlich wie diese Debugmethode funktioniert?
Das ganze liest sich schlimmer als es ist. Am Papier geht
sowas ganz schnell.
Wichtig: Bleistift verwenden und keinen Kugelschreiber.
Sonst wirds nichts mit dem ausradieren bei einem free().
Buntstifte (mehrere Farben) sorgen auch schnell mal fuer
Uebersicht.

Damit hats eigentlich noch jeder geschafft, lineare Listen
oder Baeume zu debuggen. Bei rekursiven Funktionen wirds
allerdings lustig :-)

von Dirk S. (dirk_schnitzler)


Lesenswert?

Ich finde, Karl Heinz hat den 1. Preis für ASCII-Art und anschauliches
Erklären verdient :-)

von F.Keilbach (Gast)


Lesenswert?

Ok danke an Alle dir mir dabei helfen!
Ich habe jetzt bei mir nur noch Probleme mit der Ausgabe.

void ausgabe(void)
 {
  struct telement *hzgr;
  int i=0;
  hzgr = anker;
  do
   {
  printf ("Inhalt Text1: %s", hzgr->text1);
    hzgr = hzgr->zeiger;
   }
  while (hzgr != NULL);
  printf("\n\n");
  return;
 }

Hier möchte ich die Strings am Bildschirm ausgeben.
Leider stürtzt das Programm immer ab?

von Hans (Gast)


Lesenswert?

gib deinem strukt einen constructor in dem du die string-pointer auf 0
setzt.. beim ausgeben machst etwas in die richtung
if(foo->bar==0)
  printf ("invalid pointer")
else
  printf ("string:%s",foo-bar);
ich wette noch immer gleiches problem....bzw dein malloc reserviert dir
ein byte zuwenig und du überschreibst dir dein null-byte...

damit sollte das ganze debuggen leichter gehn.. wenn z.b ein strcpy
kracht dann kannst schaun ob du überhaupt speicher in deiner
destination angelegt hast...

c ist eben eine sprache in der man sich um seinen speichern zu kümmern
hat ;) meiner erfahrung nach ist das eine der haupt-crash-gründe, dass
man speicher nicht initialisiert und pointer ins nirvana zeigen...

also immer wenn ein pointer reserviert wird auf 0 setzen (NULL ist auch
oft gebräuchlich) und wenn er freigegeben wird auch wieder 0 setzen..
das erspart arbeit beim debuggen ;)

73

von Karl H. (kbuchegg)


Lesenswert?

> Ok danke an Alle dir mir dabei helfen!
> Ich habe jetzt bei mir nur noch Probleme mit der Ausgabe.

Die hast Du nicht.
Die Ausgabefunktion ist voellig in Ordnung.
Aber die Datenstruktur die Du da zusammenbaust
ist es nicht.

Merke: Das der Absturz in ausgabe() passiert heist
nur das Du dort das Symptom siehst. Die Ursache ist
aber ganz woanders (und schon beschrieben worden).

von Karl H. (kbuchegg)


Lesenswert?

(Das kommt jetzt drauf an, welche Aenderungen Du bisher
gemacht hast. Aber ich riskiers mal:)

Mach mal folgendes:

int main(void)
 {
  anker = (struct telement*)malloc( sizeof(struct telement)) ;
  anker->zeiger=anker;
  ausgabe();
  return 0;
 }

Wenn Du Glueck hast, dann crasht dieser Code genauso (*).
Und jetzt lies nochmal durch was ich weiter oben
elendslang beschrieben habe.
Und vor allem: Benutze Deine Werkzeuge, um rauszufinden
wo genau es in der Funktion ausgabe() crasht. Dann
zieh Deine Schluesse daraus.

(*)
Glueck deshalb, da es keine Garantie dafuer gibt. Das
Program enthaelt definitv einen schweren Fehler. Wenn Du
Pech hast, dann bemerkst Du den Fehler waehrend des Entwickelns
nicht und lieferst den fehlerhaften Code an Deinen Kunden aus.
Laut Murphy, krachts dann bei dem. Und das ist wesentlich
schlechter als wenn es bei Dir kracht und Du auf den Fehler
aufmerksam wirst.

von The Daz (Gast)


Lesenswert?

Ich verstehe nicht, warum sich Leute in C++ noch mit sowas rumplagen wo
es doch die STL gibt.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

weil er es in C realisieren soll? Das er die Endung cpp verwendet liegt
entweder daran das sein Betreuer nichts taugt oder aber das doch C++
gemeint ist. Aber es schadet niemandem sowas mal manuell zu
implementieren. Nur so versteht man was da wirklich passiert und was
die Vor- und Nachteile einer verketteten Liste sind.

Matthias

von Sudras Danial (Gast)


Lesenswert?

Mach die Liste einfach richtig, dann geht sie eh!!!!

von Dirk (Gast)


Lesenswert?

Hi,

ich muss auch mal nen Lob loswerden und hoffe jemand ist so nett und
stellt es in Wiki rein. In einigen C Büchern finde ich es nicht so
verstaendlich beschrieben, vielleicht liegt es auch an der Grafik.

Gruß,

Dirk

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.