Ferris Geschrieben 27. März 2001 Teilen Geschrieben 27. März 2001 Hallo Ich hab hier ein kleines Problem, dass mich langsam in den Wahnsinn treibt. In dem Programm sollen Buchtitel erfasst werden, und zwar in einem dynamischen Array. Da die Buchtitel strings sind, brauche ich ein Array, was wieder Zeiger auf char-Arrays beinhaltet. Solange ich das ganze in main mache, gibt es auch keine Probleme. Das Programm ist ANSI-C, nur die Kommentare sind C++. #include<stdio.h> #include<string.h> #include<stdlib.h> int main(void){ char** pt_pt_Buecher; char Temp[30]; int Index = 0; //....bla scanf("%s", Temp); if(Index==0){ pt_pt_Buecher=(char**)malloc(1*sizeof(char*)); } else{ pt_pt_Buecher=(char**)realloc(pt_pt_Buecher, (1+Index)*sizeof(char*)); } *pt_pt_Buecher=(char*)malloc((strlen(Temp)+1)*sizeof(char)); strcpy(*pt_pt_Buecher[Index], Temp); Index++; //...bla return 0; } Jetzt will ich aber die Buchtiteleingabe und Speicherallozierung in einer Funktion haben und übergebe das Array und den Index an die Funktion. void input_record(char ***Buch, int Index){ char Temp[30]; scanf("%s", Temp); if(Index==0){ *Buch=(char**)malloc(1*sizeof(char*)); } else{ *Buch=(char**)realloc(*Buch, (1+Index)*sizeof(char*)); } **Buch=(char*)malloc((strlen(Temp)+1)*sizeof(char)); strcpy(*Buch[Index], Temp); } int main(void){ char** pt_pt_Buecher; char Temp[30]; int Index = 0; //...bla input_record(&pt_pt_Buecher, Index); Index++; //...bla } Wenn ich hier nun den ersten string erfasse, funktioniert auch alles. Beim zweiten string funktioniert auch noch die Zeile mit realloc, das daruffolgende malloc allokiert den Speicher jedoch nicht an der Stelle, wo ich will und strcpy kopiert meinen temporären string ins Nirvana. Wo ist der Haken??? Danke und Gruss Ferris [ 28. März 2001: Beitrag editiert von: Ferris ] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 27. März 2001 Autor Teilen Geschrieben 27. März 2001 JAU! Ich hab den Fehler gefunden. Aber nicht in meinem Editor, sondern als ich mir nochmal den Code hier angeschaut hab. So ist's richtig: (*Buch)[Index]=(char*)malloc((strlen(Temp)+1)*sizeof(char)); strcpy((*Buch)[Index], Temp); Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 28. März 2001 Teilen Geschrieben 28. März 2001 nur so als tip neben bei. dynamischer wird das ganze, wenn du eine liste daraus baust. ist auch ein wenig einfacher zu realisieren. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 29. März 2001 Autor Teilen Geschrieben 29. März 2001 Hallo maddin Ich habe Deinen Vorschlag mal aufgegriffen und meine Buchtitel in eine einfach verkettete Liste gepackt. #include<stdio.h> #include<stdlib.h> #include<ansi_c.h> struct Daten{ char Titel[30]; struct Daten *Next; }; struct Daten *First; //Funktionsprototypen void Satz_anfuegen(char*); int main(void){ char Temp[30]; //.... scanf("%s", Temp); Satz_anfuegen(Temp); //... return 0; } void Satz_anfuegen(char Temp[]){ struct Daten *pt_Temp; if(First==NULL){ First = malloc(sizeof(*First)); strcpy(First->Titel, Temp); First->Next = NULL; } else{ pt_Temp = First; while(pt_Temp->Next != NULL){ pt_Temp = pt_Temp->Next; } pt_Temp->Next = malloc(sizeof(*pt_Temp)); pt_Temp = pt_Temp->Next; strcpy(pt_Temp->Titel, Temp); pt_Temp->Next = NULL; } } Was mich bei der Sache stört ist, dass meine Struktur und der Strukturzeiger First global sind. Eine andere Möglichkeit habe ich bisher jedoch nicht gefunden. Wenn ich meine Struktur und den Struktur zeiger in main deklariere, kann ich den Strukturzeiger nicht an eine Funktion übergeben, weil es ihn ja praktisch noch garnicht gibt. Muss ich erst einmal eine leere Struktur initialisieren oder gibt es da vielleicht doch eine andere Möglichkeit? Hat da jemand ne Idee? Gruss Ferris [ 29. März 2001: Beitrag editiert von: Ferris ] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 29. März 2001 Teilen Geschrieben 29. März 2001 ich habe es normalerweise immer so gemacht, das ich eine struktur liste erstellt habe und darin einen zeiger auf das erste listenelement hatte. den funktionen müssen dann allerdings noch die liste übergeben bekommen. dadurch ist der zeiger nicht mehr global. ps: ich hatte auch noch irgendwo den code, ich weiß bloß nicht mehr genau wo. ich kann ja mal suchen wenn du willst. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ketzer Geschrieben 30. März 2001 Teilen Geschrieben 30. März 2001 Ich hatte zwar leider keine Zeit mich länger mit dem Problem zu beschäftigen, aber könntest du die Struct def. und den First pointer nicht lokal als Static deklarieren? Denn außerhalb der anfuegen funktion wird die Struktur ja nicht verwendet. Und bei jedem Funktionsaufruf hätte der First pointer auch wieder den selben wert (Anfang der Liste.) Und nur weil die Struktur in main unbekannt ist, ändert sich ja nichts an der Datenspeicherung, so daß in der anfuegen funktion alles beim alten wäre. Grüße Ketzer p.s. Warum ab dem 2. Mal realloc? Zum suchen etc. habe ich schon oft im nach hinein gemerkt das ein previous pointer manchmal hifreich ist, aber wenig mehr aufwand verursacht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 30. März 2001 Teilen Geschrieben 30. März 2001 das problem ist, das man den zeiger auf das erste element immer brauch, wenn man auf die liste zugreifen will. also nicht bloß bei der funktion zum anfügen sondern auch bei vielleicht noch folgenden funktionen zum suchen oder, oder ... ps: ich habe die erfahrung gemacht, das zum suchen ein baum eine sehr gute wahl ist. und der macht auch bloß geringfügig mehr arbeit. pps: meine zweite erfahrung ist, das es am allereinfachsten ist die stl zu verwenden. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 30. März 2001 Teilen Geschrieben 30. März 2001 ich habe meine code zwar nich mehr gefunden, aber ich hab mal deinen überarbeitet: struct Daten { char Titel[30]; struct Daten *Next; }; typedef struct Liste { struct Daten First; }Liste; //Funktionsprototypenvoid Satz_anfuegen(Liste*, char*); int main(void) { char Temp[30]; Liste* p_list = (Liste*) malloc (sizeof (Liste) ); p_list->First = NULL; //.... scanf("%s", Temp); Satz_anfuegen(list, Temp); //... return 0; } void Satz_anfuegen(Liste* list char Temp[]) { struct Daten *pt_Temp; if(list->First==NULL) { list->First = malloc(sizeof(*First)); strcpy(list->First->Titel, Temp); list->First->Next = NULL; } else { pt_Temp = list->First; while(pt_Temp->Next != NULL) { pt_Temp = pt_Temp->Next; } pt_Temp->Next = malloc(sizeof *pt_Temp)); pt_Temp = pt_Temp->Next; strcpy(pt_Temp->Titel, Temp); pt_Temp->Next = NULL; } } dadurch verschwindet der globale zeiger auf die daten. [ 30. März 2001: Beitrag editiert von: maddin ] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 30. März 2001 Autor Teilen Geschrieben 30. März 2001 <BLOCKQUOTE><font size="1" face="Verdana, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von Ketzer: Ich hatte zwar leider keine Zeit mich länger mit dem Problem zu beschäftigen, aber könntest du die Struct def. und den First pointer nicht lokal als Static deklarieren? Denn außerhalb der anfuegen funktion wird die Struktur ja nicht verwendet. Und bei jedem Funktionsaufruf hätte der First pointer auch wieder den selben wert (Anfang der Liste.) Und nur weil die Struktur in main unbekannt ist, ändert sich ja nichts an der Datenspeicherung, so daß in der anfuegen funktion alles beim alten wäre. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 30. März 2001 Autor Teilen Geschrieben 30. März 2001 Oh cool, Danke maddin Das werde ich gleich mal ausprobieren. Und was die STL angeht. C++ fange ich gerade erst an und bin von STL noch weit entfernt. In drei Monaten vielleicht. Gruß Ferris Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ketzer Geschrieben 30. März 2001 Teilen Geschrieben 30. März 2001 malloc Vs. realloc: Nein die daten gehen definitiv nicht verloren. Sonst hätte keine meiner Listen funktioniert. Durch ein 2. aufrufen von malloc bekommst du lediglich einen zweiten Speicherbereich zugewiesen, der völlig unabhängig von ersten ist. keine Global Variablen: Also die struktur definition würde ich eigendlich in eine eigene *.h packen, allerdings lohnt sich dies bei dem begrenzten Umfang der Sruktur wohl nicht so. main() { DATEN *First; anfuegen(temp,First); } Durch die Übergabe den Pointers, braucht dieser nicht mehr Global zu sein. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 30. März 2001 Autor Teilen Geschrieben 30. März 2001 Hallo maddin Ich werde aus Deinem code nicht so ganz schlau. An zwei Stellen meckert auch der compiler. Das eine war wohl nur ein Tipfehler. Satz_anfuegen(list, Temp); sollte wohl Satz_anfuegen(p_list, Temp); heissen Aber die Zuweisung: p_list->First = NULL; kann irgendwie nicht gehen. Wenn ich das richtig verstehe ist doch First selbst eine Struktur vom Typ Daten in einer Struktur vom Typ Liste. Kann ich NULL an eine Struktur zuweisen? Mein compiler sagt ne. In der Funltion selber bekomme ich die gleiche Fehlermeldung. Ich probiers weiter... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 30. März 2001 Autor Teilen Geschrieben 30. März 2001 Hallo Ketzer Wenn ich in meinem code ganz oben das realloc durch malloc ersetze sind die Daten bei mir futsch. Wahrscheinlich weil ich dann das malloc auf *Buch anwende und *Buch immer gleich ist. Da müsste dann wohl auch über einen Index gehen. Werde ich nachher auch mal ausprobieren, bin aber jetzt erstmal zwei Stündchen in der Stadt, mein neues C++ Buch abholen. Urlaub ist schon was feines. Mit Stroustrup hatte ich mich wohl etwas übernommen und das Buch finde ich auch zu chaotisch und nicht gerade geeignet für den Einstieg in C++. PS: Kann es sein, dass es Standard ist, so eine Struktur für eine Liste global zu halten? In allen Büchern, die ich hab ist das nämlich so. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 30. März 2001 Teilen Geschrieben 30. März 2001 ohh, der stern macht es aus. die struktur Liste sollte keine struktur vom typ Daten enthalten sondern einen zeiger auf eine Struktur von typ daten. dann sollte das aber zumindest gehen. den ersten fehler hast du ja schon richtig erkannt. so ist das halb, wenn man zu faul ist den sch*** selber zu machen und sich code kopiert Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 30. März 2001 Teilen Geschrieben 30. März 2001 <BLOCKQUOTE><font size="1" face="Verdana, Helvetica, sans-serif">Zitat:</font><HR> Original erstellt von Ferris: PS: Kann es sein, dass es Standard ist, so eine Struktur für eine Liste global zu halten? In allen Büchern, die ich hab ist das nämlich so. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 30. März 2001 Autor Teilen Geschrieben 30. März 2001 <BLOCKQUOTE><font size="1" face="Verdana, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von Ketzer: malloc Vs. realloc: Nein die daten gehen definitiv nicht verloren. Sonst hätte keine meiner Listen funktioniert. Durch ein 2. aufrufen von malloc bekommst du lediglich einen zweiten Speicherbereich zugewiesen, der völlig unabhängig von ersten ist. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maddin Geschrieben 2. April 2001 Teilen Geschrieben 2. April 2001 das wäre nicht nur sehr umständflich sondern aúch sehr unklug, da mir jetzt kein weg einfallen würde, wie man etwas unbekannter übergeben soll. beipiel: void funktion (struct Struktur* pt) { struct Struktur { // ... } // ... } die funktion bekommt zwar einen zeiger auf eine struktur übergeben, kennt die struktur aber noch nicht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ferris Geschrieben 2. April 2001 Autor Teilen Geschrieben 2. April 2001 Jetzt wo Du's sagst - unklug ist da noch sehr milde ausgedrückt... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ketzer Geschrieben 4. April 2001 Teilen Geschrieben 4. April 2001 Original erstellt von Ferris: <STRONG>Ich hab mir das nochmal durch den Kopf gehen lassen. Du sprichst jetzt von Listen. Mein erstes Beispiel war aber keine Liste sondern ein dynamisches Array. Und da muss ich realloc nehmen. Den Rückgabewert von malloc an das Array über Index zurückgeben, so wie ich mir das dann vorgestellt hab, kann auch nicht gehen, da es diesen Teil des Arrays ja noch garnicht gibt. </STRONG> Oh, sorry. Nach dem im 2. Code Segment von Verkettentenlisten "gesprochen" wurde, habe ich dem obigen Beispiel keine Beachtung mehr geschenkt. Ich hatte mich schon gefragt welche Daten dir bei der Liste abhanden kommen können!?!?! Denn eigendlich fordert man ja nur neuen Speicherplatz an. Und da dort noch nix steht kann auch nix gelöscht werden. Alles lokal: Doch das geht void was_weiss_ich(void *first) { struct blabla {} //Anschließender Typecast auf Typus "struct blabla" } Grüße Ketzer p.s. Wobei ich die Struktur nicht lokal halten würde, da sie logisch nicht lokal ist. (Wird halt nicht nur in einer Funktion benutzt) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.