Dynamische Speicherverwaltung für zweidimensionales Array
-
Hallo,
um ein eindimensionales int-Array dynamisch zu erzeugen macht man ja einfach
int *zahl; zahl=(int *)malloc(2 * sizeof(int));
und kann dann mit
p[0]=1; //oder *p=1; p[1]=2; //oder *(p+1)=2;
bequem darauf zugreifen.
Wie macht man sowas mit zweidimensionalen Arrays? (Die Tutorials und Bücher, die ich mir bisher angeschaut habe, beschreiben alle nur den eindimensionalen Fall.)
Ich habe bereits probiert, einfach einen Doppelzeiger (also **zahl) zu deklarieren und damit herumprobiert, wie es "logisch" funktionieren "könnte". Es funktioniert aber leider nicht, so wie ich es mir vorstelle.Kann mir jemand dazu ein Beispiel machen?
Viele Grüße,
SiegfriedPS: Ich habe hier (http://www.c-plusplus.net/forum/viewtopic.php?t=206606) schon gelesen, dass man malloc nicht explicit casten soll... Mein Lern-Buch macht es aber und ich bin als Anfänger erstmal nur froh, wenn es einfach nur funktioniert
-
Dazu brauchst du keinen Doppelzeiger. Mach es einfach so:
//wenn du ein Array mit x*y Elementen haben willst: int *zahl=malloc(breite * hoehe * sizeof(int)); //Zugriff auf Element (x,y) geht dann so: zahl[y*breite+x]
Hier auch ein schöner Artikel zu dem Thema (auch zu mehr als 2 Dimensionen):
http://www.developia.de/developia/viewarticle.php?cid=19547&page=1EDIT: Die Rückgabe von malloc castet man in C nicht! In C++ muss man es allerdings, das kann schon verwirren...
-
Du kannst in C99 auch sagen:
//wenn du ein Array mit x*y Elementen haben willst: int zahl[breite][hoehe]; //Zugriff auf Element (x,y) geht dann so: zahl[x][y]
-
Danke!!!
µngbd schrieb:
Du kannst in C99 auch sagen:
//wenn du ein Array mit x*y Elementen haben willst: int zahl[breite][hoehe]; //Zugriff auf Element (x,y) geht dann so: zahl[x][y]
Ist ja aber nicht dynamisch
Habe gerade hier (http://www.c-plusplus.net/forum/viewtopic-var-t-is-39489.html) noch eine super Lösung gefunden:
int main() { const int FirstDim = 4; const int SecDim = 5; // 1. Schritt: Dynamische Array von Zeigern anlegen: int** p2DimArr = new int*[FirstDim]; // 2. Schritt: An jeden Zeiger ein Array hängen for (int i = 0; i < FirstDim ; i++) p2DimArr[i] = new int[SecDim]; // mit dem neuen 2-dimensionalen Array arbeiten p2DimArr[0][0] = 42; //... // alles wieder löschen for (int j = 0; j < FirstDim ; j++) delete [] p2DimArr[j] ; delete [] p2DimArr; }
-
Ist ja aber nicht dynamisch
Wieso nicht?
-
Ist ja aber nicht dynamisch
Doch in C99 gibt es (leider) dynamische Arrays.
Habe gerade hier (http://www.c-plusplus.net/forum/viewtopic-var-t-is-39489.html) noch eine super Lösung gefunden:
Welche Programmiersprache willst du denn nun programmieren? C oder C++? Wenn du C programmieren willst, dann schau nicht nach Antworten in der C++-FAQ. Denn der Code ist nicht C kompatibel (und dazu noch kein besonders gutes C++)! Wenn du C++ programmieren willst, dann stell die Frage im C++ und nicht im C Forum!
-
int** p2DimArr = new int*[FirstDim];
Schade, new ist nicht deklariert. Was muss ich machen, damit das läuft?
-
µngbd schrieb:
int** p2DimArr = new int*[FirstDim];
Schade, new ist nicht deklariert. Was muss ich machen, damit das läuft?
einen vernünftigen compiler benutzen, der das kann
-
µngbd schrieb:
int** p2DimArr = new int*[FirstDim];
Schade, new ist nicht deklariert. Was muss ich machen, damit das läuft?
new gibt es nur in C++. Hier bist Du im C-Forum. Also hier gibt es kein new. Willst Du mit Gewalt new nehmen, mußt Du eigentlich damit ins C++-Forum gehen. Aber Du könntest das, was man mit new macht, auch mit malloc machen. Daher die Frage: new oder malloc, was ist Dein Begehr?
-
Habe gerade hier (http://www.c-plusplus.net/forum/viewtopic-var-t-is-39489.html) noch eine super Lösung gefunden:
Die ist aber grundlegend anders als die von _matze, nicht nur syntaktisch. Da hast du nicht einen Block, sondern mehrere, die mit Zeigern verbunden sind. Zwei Zeilen zu vertauschen geht somit schneller. Die Entscheidung zwischen den beiden sollte die Datenstruktur und nicht die Syntax zum Thema haben.
-
Also wenn ich diese Methode, die 'new' verwendet benutze, lässt sich das in meiner .c-Datei problemlos mit gcc compilieren
-
vernuenftig0r schrieb:
µngbd schrieb:
int** p2DimArr = new int*[FirstDim];
Schade, new ist nicht deklariert. Was muss ich machen, damit das läuft?
einen vernünftigen compiler benutzen, der das kann
aber der würde wiederum keine pointer kennen.
-
Siegfried1 schrieb:
Also wenn ich diese Methode, die 'new' verwendet benutze, lässt sich das in meiner .c-Datei problemlos mit gcc compilieren
Nein! new und delete sind Schlüsselwörter der Sprache C++. Wenn du C programmieren willst, musst die entsprechenden Äquivalente malloc und free benutzen (außerdem gibt's noch calloc und realloc, aber das nur am Rande).
Also nochmal ganz klar: du kannst keine reinen C++-Sprachmittel in C benutzen! Nicht möglich (wird dir der Compiler auch sagen)! Es ist einfacher, Autoräder am Motorrad zu befestigen...
-
Basher schrieb:
vernuenftig0r schrieb:
µngbd schrieb:
int** p2DimArr = new int*[FirstDim];
Schade, new ist nicht deklariert. Was muss ich machen, damit das läuft?
einen vernünftigen compiler benutzen, der das kann
aber der würde wiederum keine pointer kennen.
Hmm Also mein C++-Compiler kennt pointer?
-
rüdiger schrieb:
Ist ja aber nicht dynamisch
Doch in C99 gibt es (leider) dynamische Arrays.
Wieso "leider"?
-
Tim schrieb:
rüdiger schrieb:
Ist ja aber nicht dynamisch
Doch in C99 gibt es (leider) dynamische Arrays.
Wieso "leider"?
Ich finde VLAs sind ein unausgewogenes Feature. Es gibt keinen Weg für die Anwendung festzustellen, ob die Stackgrenzen gesprengt werden. Bei man: alloca gibt es ja immerhin noch den Weg, dass die Funktion das intern prüft und fehlschlägt (wobei zB die GCC/glib alloca Funktion leider noch nicht einmal das tut). Aber wie soll man in der Runtime bei einem VLA auf so ein Problem reagieren? (gar nicht? Programm abbrechen? Stack wieder herstellen? ...)
-
rüdiger schrieb:
Tim schrieb:
rüdiger schrieb:
Ist ja aber nicht dynamisch
Doch in C99 gibt es (leider) dynamische Arrays.
Wieso "leider"?
Ich finde VLAs sind ein unausgewogenes Feature. Es gibt keinen Weg für die Anwendung festzustellen, ob die Stackgrenzen gesprengt werden. Bei man: alloca gibt es ja immerhin noch den Weg, dass die Funktion das intern prüft und fehlschlägt (wobei zB die GCC/glib alloca Funktion leider noch nicht einmal das tut). Aber wie soll man in der Runtime bei einem VLA auf so ein Problem reagieren? (gar nicht? Programm abbrechen? Stack wieder herstellen? ...)
das ist wie mit rekursionen. du musst vorher wissen, wie viel es maximal werden kann.