AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein C Speicherzugriffsfehler bei verketteter Liste
Thema durchsuchen
Ansicht
Themen-Optionen

C Speicherzugriffsfehler bei verketteter Liste

Ein Thema von Hybrid666 · begonnen am 20. Okt 2010
Antwort Antwort
Hybrid666

Registriert seit: 15. Jul 2006
Ort: Erster Stock
250 Beiträge
 
Delphi 7 Personal
 
#1

C Speicherzugriffsfehler bei verketteter Liste

  Alt 20. Okt 2010, 09:49
Hallo,

ich muss für mein info II Labor eine Aufgabe bearbeiten, bei der Daten in eingelesen werden, in eine einfach verkettete liste gespeichert werden sollen, in eine Binärdatei geschrieben werden sollen, liste soll gelöscht werden und aus der Datei neu aufgebaut werden.

Das Einlesen funktioniert, die Daten werden erfolgreich ausgegeben (also sind wirklich in der liste), die Datei wird korrekt gespeichert und die liste wird erfolgreich gelöscht. Nur beim einlesen der Datei gibt es probleme.

Hier erstmal alle Dateien:

malloc1.c:
Code:
/* Dateiname: malloc1.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "prodlist.h"
#include "prodinfo.h"


int main (void)
{
   int anzahl, count;
   char buffer [20];
   ProdListe * liste;
   ProdInfo * temp;
   initListe (&liste);
   printf ("Anzahl der Produkte: ");
   fgets (buffer, 19, stdin);
   sscanf (buffer, "%i", &anzahl);
   for (count = 0; count < anzahl; count++) {
      einfuegenListe (&liste, einlesenProdukt ());
   }
   SaveList ("DATA.DAT", liste);
   while ((temp = naechstesProdukt (&liste)) != NULL) {
      ausgebenProdukt (temp);
   }
   KillList (&liste);
   initListe (&liste);
   ReadList ("DATA.DAT", &liste);
   while ((temp = naechstesProdukt (&liste)) != NULL) {
      ausgebenProdukt (temp);
   }
   return 0;
}
prodinfo.h:
Code:
#ifndef PRODINFO_H_

#define PRODINFO_H_

typedef

    struct prodinfo { char name [20];

                      double preis;

    }

ProdInfo;

#endif



void ausgebenProdukt (ProdInfo * prod);

/* Ausgeben der Produktinformation am Bildschirm */



ProdInfo * einlesenProdukt (void);

/* Einlesen der Produktinformation,

   Beschaffen von Speicher für die Info

   und Rueckgabe eines Zeigers auf die Info */
prodinfo.c:
Code:
#include <stdio.h>
#include <stdlib.h>
#include "prodinfo.h"

ProdInfo * einlesenProdukt (void) {
   ProdInfo * new;
   char buffer [100];
   new = malloc (sizeof (ProdInfo));
   printf ("Bitte Produktnamen eingeben: ");
   fgets (new->name, 19, stdin);
   printf ("Bitte Preis eingeben: ");
   fgets (buffer, 99, stdin);
   sscanf (buffer, "%lf", &new->preis);
   return new;
}

void ausgebenProdukt (ProdInfo * prod) {
   printf ("Produktname: %sPreis: %lf\n", prod->name, prod->preis);
}
prodlist.h:
Code:

#include "prodinfo.h"



#ifndef PRODLIST_H_

#define PRODLIST_H_

typedef

    struct prodliste {

        ProdInfo * info;

        struct prodliste * next;



    } 

ProdListe;

#endif  

    void initListe (ProdListe ** liste);

    /* Angegebene Liste wird initialisiert mit NULL */

 

    void einfuegenListe (ProdListe ** liste, ProdInfo * produkt);

    /* Angegebenes Produkt wird in die gegebene Liste eingefuegt */



    ProdInfo * naechstesProdukt (ProdListe ** liste);

    /* Das naechste Produkt in der Liste wird zurueckgegeben,

       die Liste wird fortgeschaltet, so dass sie jetzt auf die

       Restliste ohne das zurückgegebene Element zeigt

    */

     

   void SaveList (char * FileName, ProdListe * liste);

   void ReadList (char * FileName, ProdListe ** liste);

   void KillList (ProdListe ** liste);
prodlist.c:
Code:
#include <stdio.h>
#include <stdlib.h>
#include "prodlist.h"
#include "prodinfo.h"

static ProdListe * pos;

void initListe (ProdListe ** liste) {
   *liste = NULL;
   pos = NULL;
}

void einfuegenListe (ProdListe ** liste, ProdInfo * produkt) {
   ProdListe * ref;
   if (*liste == NULL) {
      *liste = malloc (sizeof (ProdListe));
      (*liste)->next = NULL;
      (*liste)->info = produkt;
      pos = *liste;
   } else {
      ref = *liste;
      while (ref->next != NULL) { ref = ref->next; }
      ref->next = malloc (sizeof (ProdListe));
      ref->next->next = NULL;
      ref->next->info = produkt;
   }
}

ProdInfo * naechstesProdukt (ProdListe ** liste) {
  ProdInfo * res;
  if (pos != NULL) {
    res = pos->info;
    pos = pos->next;
    return res;
  } else { return NULL; }
}

void SaveList (char * FileName, ProdListe * liste) {
   FILE * fp;
   ProdListe * ref;
   fp = fopen (FileName, "wb");
   ref = liste;
   while (ref != NULL) {
      fwrite ((*ref).info, sizeof (ProdInfo), 1, fp);
      ref = ref->next;
   } 
   fclose (fp);
}

void ReadList (char * FileName, ProdListe ** liste) {
  FILE * fp;
  ProdInfo * r;
  KillList (liste);
  *liste = NULL;
  fp = fopen (FileName, "rb");
  while (fread (r, sizeof (ProdInfo), 1, fp) > 0) {
    //printf ("\n\n%s%lf", r->name, r->preis);
    einfuegenListe (liste, r);
  }
  fclose (fp);
}

void KillList (ProdListe ** liste) {
  if (*liste != NULL) {
    if ((*liste)->next != NULL) { KillList (&(*liste)->next); } 
    free ((*liste)->info);
    free ((*liste));
    *liste = NULL;
  }
}
ich habe rausgefunden, das in der ReadFile Routine der Speicherzugriffsfehler beim aufruf von einfuegenListe auftritt. Aber warum? das einfügen hat davor ja auch funktioneirt und die liste sollte beim aufruf von readfile komplett leer (=NULL) sein.

Wäre echt super wenn da jemand was zu sagen könnte (auch wenns nur ideen sind warum es nicht geht).
Compilen tut das ganze ohne probleme. Und der bequemlichkeit halber von euch lade ich die sourcefile in den Anhang hoch, so müsst ihr falls ihrs probieren wollt nichtmehr kopieren und einfügen .

Ach und bitte nichts über funktionsnamen, etc meckern, die sind vorgegeben (ich bin auch nicht zufrieden), ebenso wie die Prototypen in den .h files (die sind auch vorgegeben).

Bin für jede hilfe dankbar!

hybrid666


EDIT:

also ich habe nun mal die einfuegenListe so editiert:
Code:
void einfuegenListe (ProdListe ** liste, ProdInfo * produkt) {
   ProdListe * ref;
   if (*liste == NULL) {
      printf ("Liste ist NULL\n");
      *liste = malloc (sizeof (ProdListe));
      printf ("Speicher allokiert...\n");
      (*liste)->next = NULL;
      printf ("Naechstes Element genullt\n");
      (*liste)->info = produkt;
      printf ("Info auf Produkt gesetzt\n");
      pos = *liste;
      printf ("pos gesetzt\n");
   } else {
      printf ("liste nicht NULL\n");
      ref = *liste;
      printf ("ref auf liste gesetzt!\n");
      while (ref->next != NULL) { ref = ref->next; }
      printf ("schleife durchgelaufen\n");
      ref->next = malloc (sizeof (ProdListe));
      printf ("speicher allokiert\n");
      ref->next->next = NULL;
      printf ("next genullt\n");
      ref->next->info = produkt;
   }
}
Das Programm stürzt ab, da es bei ReadFile beim aufruf von einfuegen liste die liste, die durch initliste genullt wurde, als nicht Null erkennt, sofort in die else bedingung läuft und dann bei der while schleife abstürzt (ist klar, da next ja nciht existiert!). Aber warum ist die liste nicht null? ich hab sie sogar vorsichtshalber in der readfile funktion genullt (*liste = NULL).
Ich weiß nimmer weiter...
Angehängte Dateien
Dateityp: zip aufg_4.zip (2,2 KB, 0x aufgerufen)

Geändert von Hybrid666 (20. Okt 2010 um 10:35 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:03 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz