2 dim. Array Struktur
-
Moinsen! Ich habe ein Problem dynamisch ein zwei dim. Array in C zu erzeugen.
Das ganze soll mit einer Struktur passieren. Die einzelnen Schritte der dynamischen Speicherverwaltung für ein zwei dim. Array sind mir klar(Speicher für Zeigervektor, Speicher für Daten, Zeigervektor initialisieren, Daten initialisieren, Speicher freigeben) und wie man es in code gießt.Nur ich habe Probleme es mit einer Struktur zu machen.
Ich hoffe mir kann jemand einen Denkanstoß geben
-
Im Prinzip macht es keinen Unterschied ob man das für einen Strukttypen oder für pod-typen ("plain old data") macht. Von daher sehe ich nicht dein konkretes Problem?
-
Philly schrieb:
Speicher für Zeigervektor,
Speicher für Daten,
Zeigervektor initialisieren,
Daten initialisieren,
Speicher freigebenBei welchemn deiner 5 Schritte hast du denn Probleme?
Nenn mal den Zeigervektor lieber Zeilenvektor.
Dann fehlen dir noch die Spaltenvektoren, die dann auf die struct verweisen.
Also die Elemente vom Zeilenvektor zeigen auf Spaltenvektoren.
Jedes Element eines Spaltenvektors zeigt auf eine struct.struct struct +-------+ +-------+ +-->| int .... +-->| int .... Zeilen Spalten | | +--------+ +-------+-------+-------+-------+-.... |**struct| ---> |*struct|*struct|*struct|*struct|*... +--------+ +-------+-------+-------+-------+-.... |**struct| -+ +--------+ | +-------+-------+-------+-------+-.... |**struct| +-> |*struct|*struct|*struct|*struct|*... +--------+ +-------+-------+-------+-------+-.... \ \ +-------+-------+-------+-------+-.... +-> |*struct|*struct|*struct|*struct|*... +-------+-------+-------+-------+-....
-
Also ich müsste dann ja ein **Zeiger in meiner Struktur haben. Ich möchte dann in einer Funktion den Speicher verwalten, außerhalb von main. Wenn ich das dann so gemacht habe kann ich die Daten nicht initialisieren...
-
Oh deine Antwort DirkB habe ich jetzt erst gesehen! Danke für die Veranschaulichung, so ähnlich kenne ichs für ohne struct. Ich habe Probleme die Struktur mit den jeweiligen Elementen zu erstellen.
-
Ich hab dir einen ***Zeiger gezeigt. Da musst du jede struct mit malloc besorgen.
Du kannst auch wie bisher mit **Zeigern arbeiten.
Sonst besorgst du dir ja Speicher mit malloc:
malloc(Arraygröße*sizeof(struct));
Da sind dann die structs schon "drin"Zeilen Spalten +--------+ +-------+-------+-------+-------+-.... | *struct| ---> | struct| struct| struct| struct| ... +--------+ +-------+-------+-------+-------+-.... | *struct| -+ +--------+ | +-------+-------+-------+-------+-.... | *struct| +-> | struct| struct| struct| struct| ... +--------+ +-------+-------+-------+-------+-.... \ \ +-------+-------+-------+-------+-.... +-> | struct| struct| struct| struct| ... +-------+-------+-------+-------+-....
Zeig mal deinen Code. Dann kann man besser sehen, wo es bei dir hakt.
-
Philly schrieb:
Oh deine Antwort DirkB habe ich jetzt erst gesehen! Danke für die Veranschaulichung, so ähnlich kenne ichs für ohne struct. Ich habe Probleme die Struktur mit den jeweiligen Elementen zu erstellen.
Was genau ist denn dein Problem dabei? Geht eigentlich genau so wie bei allen anderen Datentypen auch.
Im übrigen dürfte dir an DirkBs ausgezeichnetem Bild auffallen, dass die Datenstruktur nicht wirklich ein 2 dimensionales Array ist, sondern eher eine Art Liste von Listen, die, im Gegensatz zu Arrays, irgendwo verteilt im Speicher liegen.
-
Also ich habe es so gelehrt bekommen das die Daten mehrdimensionaler Listen auch hinter einander im Speicher liegen.
hier mein Versuch:
#include<stdio.h> #include<stdlib.h> #include<malloc.h> void InitialisiereFeld(struct sData *pData); typedef struct sData { int intZeilenFeld, intSpaltenFeld; int **pintFeld; }; int main(void) { sData Data; typedef sData tData; tData *pData= &Data; InitialisiereFeld(pData); return EXIT_SUCCESS; } void InitialisiereFeld(struct sData *pData) { int intZeile, intSpalte, intlaufe, intFehler; typedef sData tData; pData->pintFeld=NULL; scanf("Anzahl der Zeilen des Feldes:", &pData->intZeilenFeld); scanf("Anzahl der Spalten des Feldes:", &pData->intSpaltenFeld); /*Speicher für Zeigervektor*/ pData->pintFeld= (pData->pintFeld**) malloc(pData->intZeilenFeld*sizeof(tData*)); if(pData->pintFeld == NULL) intFehler=-1; /*Speicher für Daten*/ if(!intFehler) { pData->pintFeld[0] = (tData*) malloc(pData->intZeilenFeld*pData->intSpaltenFeld*sizeof(tData)); if(pData->pintFeld[0] == NULL) intFehler = -2; } /*Zeigervektor initialisieren*/ if(!intFehler) for(intlaufe=1; intlaufe < pData->intZeilenFeld; intlaufe++) pData->pintFeld[intlaufe] = pData->pintFeld[intlaufe-1]+pData->intSpaltenFeld; /*Daten initialisieren*/ for(intZeile=0; intZeile != pData->intZeilenFeld; intZeile++) { for(intSpalte=0; intSpalte != pData->intSpaltenFeld ; intSpalte++) { pData->pintFeld[intZeile][intSpalte]= 0; } } //..... }
-
Alles total konfus.
Es hilft auch nicht, unter einem anderen Namen die gleiche Problematik wieder anzufragen.
Du weißt nicht was ein Array ist.
Du weißt nicht was ein Zeiger/dyn.Speicher ist.
Du weißt nicht mit struct umzugehen.
Du weißt nicht mit typedef umzugehen.
...
Alles denkbar schlechte Voraussetzungen, um hier gemachte Vorschläge überhaupt ansatzweise sinnvoll anzuwenden.
-
Philly schrieb:
Also ich habe es so gelehrt bekommen das die Daten mehrdimensionaler Listen auch hinter einander im Speicher liegen.
Tja, falsch gelernt.
hier mein Versuch:
- Zeile 5 muss unbedingt hinter der struct-Definition stehen. Das Problem hatten wir kürzlich schon einmal. Warst du das?
- Du machst in Zeile 7 einen typedef ohne Namen. Hast du eigentlich irgendeinen Plan, warum man da typedef benutzt oder hast du das einfach irgendwo abgeschrieben, ohne es zu verstehen?
- Hieraus folgt, dass die Benutzung des Typbezeichners sData in Zeile 17 ff nicht funktionieren kann, es sei denn, du benutzt einen C++-Compiler zum übersetzen. Tu das nicht! Ganz schlimmer Fehler!
- scanf funktioniert nicht so, wie du es benutzt. Überhaupt nicht so. Nochmal Grundlagenbuch zweite Seite lesen.
- Den Cast in Zeile 41 brauchst du nur in C++ (wo man malloc sowieso nicht so wie hier benutzen würde). Der Cast verdeckt so aber den Fehler, dass du einen C++-Compiler für C benutzt! C und C++ haben zwar gewisse Ähnlichkeiten und Kompatibilitäten, sind aber zwei ganz verschiedene Sprachen. Jedes auch nur leicht komplexere Programm ist nicht portierbar. Benutze niemals C++-Compiler für C!
- Der Cast ist zudem syntaktisch Müll.
pData->pintFeld**
ist kein Typ. Das was ich bisher beschrieben habe waren "nur" Compilerwarnungen. Dies kann gar nicht compilieren. Hast du nicht einmal versucht, deinen Code zu übersetzen? - Der Cast in Zeile 47 ist genau so unnötig. Der Cast ist dieses mal zwar syntaktisch korrekt, jedoch passt der Typ nicht! pData->pintFeld[0] ist kein
tData*
! Dies wiederum wird ein C++-Compiler niemals so fressen. Was hast du bloß gemacht? - Zeile 43 und 51: intFehler wird uninitialisiert benutzt.
- Speicherlöcher overkill! Kein einziges free im ganzen Code.
Merke: Code aus dem Internet planlos zusammen kopieren ist nicht programmieren!
edit: Wutz meint auch, dich wieder zu erkennen. Wenn er damit Recht hat, dann stimmt auch seine Folgerung: Dir fehlen zu viele Grundlagen, als dass du unsere Hinweise überhaupt verstehen könntest. Wie soll man dir da helfen können? In deinem alten Thread wurden schon sehr viele Fehler korrigiert, trotzdem sind sie immer noch in deinem Code.