Da ich länger nichts mehr mit C gemacht hab, und meine Kenntnisse wohl doch einige neue Löcher aufweisen bekomm ich immer einen Speicherzugriffsfehler(an der markierten stelle tritt es auf). Es wär schön wenn einer meinen fehler sieht und mich aufklären könnte.
#include
Programmieren - alles kontrollieren 4.941 Themen, 20.715 Beiträge
ups ist noch eine alte version mit einen kleinen Fehler:
scanf(%10s,...) soll es natürlich lauten...(sowas kommt wenn man auf zwei verschiedenen Rechner arbeitet *g)
Neue elemente in liste dürfen keine stackvariablen sein. Statt
struct Student aktu;
muss es
struct Student *aktu;
aktu=(struct Student *)malloc(sizeof(struct Student));
/*hier eigentlich noch eine fehlerbehandlung für den fall aktu==NULL*/
heißen (für malloc() und co. ist u.u. ein extra #include<malloc.h> bzw. #include<stdlib.h>erforderlich). Damit wird zudem aus
actu.???
jeweils
actu->???
Zudem hätte es statt
scanf("%d", aktu.matrikel);
auch
scanf("%d", &aktu.matrikel);
heißen müssen, denn bei scanf wird die adresse der variablen angegeben. In der malloc-version wird es also zu
scanf("%d", &aktu->matrikel);
Durch das allozieren mit malloc() wird es nötig, nach gebrauch die einzelnen elemente wieder freizugeben (z.b. in main())
for (i=0;i<ANZ;i++)
{
struct list *kill;
if((kill=liste.start)==NULL)/*zuweisen und ende wenn liste zu früh leer*/
break;
liste.start=liste.start->next;/*erstes element heraustrennen*/
free(kill);/*herausgetrenntes element freigeben*/
};
mr.escape
vielen dank für die schnelle und competente hilfe, aber meinen hauptfehler ahst du auch nicht erkannt:
einfuegen(&liste); aber zu deiner verteidigung de in umfeld war hat ich auch irgendwie zuviel bei der neuformatierung gelöscht :( (hatte das ursprünglich unter linux mit kate geschrieben und dann per usb stick auf meinen rechner mit Win und iNet zugang geschoben ;)) Mich wundert bloß das der compiler trotz falscher typ zuweisung compiliert hat??
Ich habe diesen fehler durchaus gesehen und wollte ihn, zusammen mit scanf("%d", aktu.matrikel); erwähnen, aber irgendwie ist er mir durchgeschlüpft.
Es ist wirklich seltsam, dass der compiler das schluckt. Nimmt er jetzt liste "by value" und füllt immer wieder in die leeren elemente der kopie die stackvariable rein und am ende hat man immer noch eine leere liste (und es knirscht im printf() in main()) oder nimmt er (den leeren) start-zeiger und versucht diesen als struct list * zu interpretieren (und damit zugriffsfehler in einfuegen() zu erzeugen)?
mr.escape
Er hatte damit die zugriffsfehler bei einfuegen() erzeugt.
Aber ich war wirklich frph über deine erläuterungen das malloc hatte ich an anfang noch drin, allerdings hat ich das (struct student*) an anfang vergessen so das ich es "gefrustet rausgeschmissen bin, das aktu war auch anfangs als zeiger realisiert baber wengen den zugriffsfehlern hatte ch es zwischenzeitlich mal als "element" definiert damit er sich den Speicher automatisch reserviert.
Das scanf mit zeigern arbeiten muss war mir auch klar, aber wieso muss ich das & bei scanf("%d", &aktu->matrikel) einfügen? Das aktu ist ja schon ein zeiger und erfüllt damit doch die bedingungen von scanf, oder war das nur ein grundlegender Tipp damit man es bei komplexeren programmen nicht bei variablen vergißt?
Anders ist es bei den char-arrays. Dort ist der arrayname automatisch die adresse des arrays.
Statt z.b. aktu.vorname könnte man auch &aktu.vorname[0] schreiben, denn tatsächlicht ist ja nur vorname[0] eine char variable. Darum reicht die angabe aktu.vorname bzw. aktu->vorname als zeiger auch ein char array.
Gibt man nun statt &aktu->matrikel nur aktu->matrikel an, dann interpretiert scanf() den inhalt der int variablen als adresse einer int variablen und schreibt dorthin den eingelesenen wert.
Je nach compiler und compilerflags ist der inhalt von stackvariablen und mallocspeicher undefiniert, 0 oder ein speicherschutzmuster (gedacht für den debugger, der dadurch erkennen kann, dass nicht initialisierte variablen verwendet werden, klappt natürlich nicht immer, aber recht oft).
mr.escape
Nochmal danke!