Kleines Problem mit allokiertem Speicher
-
Ich bin jetzt kein Experte und auch eher Anfänger, aber ist es egal ob du
TEST *test
oderTEST **test
deklarierst? Du willst ja schließlich ein Zeiger auf Zeiger haben.In der Whileschleife würde ich auch den zurück gegebene Zeiger auf NULL testen, also ob das Allokieren erfolgreich war, solltest du immer tun.
Dann wäre auch noch zu klären ob i in der Whileschleife nicht größer 2 wird, da du ja nur für drei Elemente Speicher angefordert hast. Ob man jetzt so für Zeiger auf Zeiger allokiert bin ich mir auch nicht sicher, dafür kann ich zuwenig C.
-
Lichtweite schrieb:
Ich bin jetzt kein Experte und auch eher Anfänger, aber ist es egal ob du
TEST *test
oderTEST **test
deklarierst? Du willst ja schließlich ein Zeiger auf Zeiger haben.Nein, er will in der main einen Zeiger haben. Nur um diesen in der Funktion zu ändern muss er einen Zeiger auf diesen Zeiger haben. Und test (vom Typ TEST*) wird durch den Adressoperator & zum Zeiger-auf-test (und da test selbst schon ein Zeiger ist, hat dieser den Typ TEST**).
-
Erstmal das alte verfahren mit Einfachzeiger:
So wie dutest[i]->
verwendest, wäre test ein Array of Pointer to struct.Du hast aber zunächst einen Pointer to struct.
Den kannst du mittest->member
(das etwas hübscher aussieht als) oder(*test).member
oder als Array(der Länge 1)test[0].member
ansprechen.Wie du siehst, ist die Arrayschreibweise schon eine Dereferenzierung.
Also entweder Array oder ->Wenn du mehr Speicher besorgst, bekommst du ein Array of struct.
Das geht dann so:test[i].member
Und da jetzt test ein Zeiger auf den Zeiger ist kommt noch die Dereferenzierung für test dazu:
(*test)[i].member
(Pointer = Zeiger)
-
Ich hab jetzt bald alle möglichen Kombinationen aus "*", ".", "->" durch. Gab größtenteils folgenden Fehler:
error: request for member 'details' in something not a structure or union
Bei meiner aktuellen Variante gibt es diesen Fehler zumindest nicht. Dafür aber einen anderen, welcher zumindest leichter zu beseitigen klingt. Auftreten tut der Fehler in Zeile 3 des Code Ausschnitts.
error: incompatible types when assigning to type 'BLUBB' from type 'struct BLUBB *'
BLUBB *speicher; speicher = (BLUBB *) calloc(1,sizeof(BLUBB)); *(test)[i]->details = speicher; *(test)[i]->details->nummer = /* [...] */
Wieso ist "speicher" vom Typ struct BLUBB *, aber "test" vom Typ BLUBB? Ich befürchte, da hat es bei mir noch nicht 100%ig klick gemacht.
Sorry, wenn ich mit so "Anfängerproblemen" nerve. C ist doch etwas komplexer als Java oder PHP. Kaum dachte ich, das mit den Zeigern verstanden zu haben, kommen Doppelzeiger und wirbeln erstmal wieder alles durcheinander.
-
Der -> Operator bindet stärker als der * Operator. Daher derefenzierts Du details. Wenn Du test dereferenziern willst musst Du (*test)[i]->details schreiben.
-
Ah super ^^ So hat es jetzt funktioniert. Danke!
Nur jetzt scheint sich mein anfängliches Problem genau umgekehrt zu haben ^^ Das ist echt ein Fass ohne Boden.
Ich hatte den Thread gestartet, weil ich für "test" in der Main Funktion Speicher allokiert hatte, "test" an ne andere Funktion (Funktion1) übergeben hatte, dort weiter Speicher allokiert hatte und dieser neue Speicher in der Main Funktion dann nicht mehr vorhanden war. Siehe ersten Post.
Nun durch die Übergabe als Doppelzeiger ist der neu allokierte Speicher in der Main Funktion vorhanden. Soweit wunderbar. Aber der Speicher, welcher anfangs in der Main Funktion allokiert wird, wird scheinbar nicht mit an Funktion1 übergeben und ist danach auch in der Main Funktion nicht mehr vorhanden. Geht das als Doppelzeiger nicht?
-
Batman schrieb:
Nun durch die Übergabe als Doppelzeiger ist der neu allokierte Speicher in der Main Funktion vorhanden. Soweit wunderbar. Aber der Speicher, welcher anfangs in der Main Funktion allokiert wird, wird scheinbar nicht mit an Funktion1 übergeben und ist danach auch in der Main Funktion nicht mehr vorhanden. Geht das als Doppelzeiger nicht?
So ganz versteh ich das nicht.
Und es geht.
Irgendwo wirst du ein Adressoperator (&) oder Dereferenzierungsoperator (*) falsch eingestzt haben.
Zeig Code (mit dem realloc Teil) , sonst wird das ein rumgestocher im Nebel.
-
Danke, der Tipp hat schon geholfen. Hatte mir nochmal alle Zugriffe auf "test" angeschaut und ich hatte beim realloc wirklich Murks gemacht.
Jetzt läuft es einwandfrei. Vielen Dank an alle Helfer!
-
Wenn Du den Speicher, der einer Variablen mittels malloc oder calloc zugewiesen war, vergrößern oder verkleinern willst, musst Du die Funktion realloc nehmen. In deinem Beispiel benutzt Du calloc. Versuchs mal mit realloc. DirkB hat schon darauf hingewiesen. Und prüfe den Rückgabewert (s. Post von Lichtweite).
-
Ja ne, bei mir geht es um 2 Sachen.
1. das dynamische Feld "test" insgesamt mit mehr Speicher ausstatten (via realloc)
2. das "test[i]->details" Element mit dem Speicher für ein struct BLUBB Element ausstatten (via calloc, da der Speicher nur neu allokiert und nicht erhöht wird)Keine Ahnung, ob ich das jetzt verständlich rüber gebracht habe ^^ Aber
das passt schon so, wie es umgesetzt ist. Und laufen tut es auch. Den realloc Part hatte ich nur nicht gepostet.Trotzdem danke für den Hinweis