Dynamisches Mehrdimensionales Array übergeben

Suchtaaa

Grünschnabel
Hey,

Vorweg: Es ist keine Hausaufgabe oder ähnliches :D

Zum Problem:
Ich stehe zurzeit vor dem Problem, ein dynamisches Mehrdimensionales Array an eine Funktion zu übergeben.

Gegooglet(?) habe ich auch schon, jedoch nichts gefunden was mir wirklich geholfen hat...
Vielleicht könnt ihr mir ja helfen, wie ich es schaffe es zu übergeben.

Danke im voraus für alle Tipps.

LG. Suchtaaa :)
 
Hi und Willkommen bei tutorials.de :),

Paar Gegenfragen:

ist es die Art von mehrdim. Array, wo jedes Unterarray nach dem Hauptarray separat erzeugt werden muss (also das Hauptarray hat nur Pointer), oder ein "einblockiges"? Oder evt. std::array oder std::vector? Im Zweifelsfall einfach codemäßig herzeigen, wie du das Array machst und wieder löscht.

Darf das Array in der Funktion geändert werden (wenn nicht kann const manche Sachen nämlich vereinfachen)?
Falls ja, sollen Änderungen in der Funktion auch nach außen wirken (Pointer/Referenz),
oder soll in der Funktion eine Kopie vom Array vorhanden sein?

Falls es nicht std::vector ist, willst oder darfst (Schule etc.) du das nicht verwenden,
oder ist vector noch unbekannt?
 
Ähhhhmm, ich weiß ehrlich gesagt nicht was du mit dem Ersten teil meinst :D
Ich bin noch nicht sehr lange am Programmieren :D

Das Array muss nicht geändert werden, nur am Anfang muss man angeben wie groß das Array werden soll und welche Zahlen es enthalten soll.

Die Vectoren sind noch unbekannt außerdem ist es in C geschrieben, nicht in C++, den Code poste ich trotzdem in C++...

Hier der Code:

C++:
#include <stdlib.h>
#include <stdio.h>


void ArrayAusgabe(int **Daten, int laenge, int breite)
{
    int i, a;

    printf("\n");

    for(i=0; i<3; i++)
        for(a=0; a<3; a++)
            printf("Daten[%d][%d] = %2d\n", i, a, Daten[i][a]);
}


void main()
{

    int **Daten;

    int i, a;
    int Spalte = 3, Zeile= 3;

    Daten = malloc(Spalte*sizeof(int));

    for(i=0; i<Spalte; i++)
        Daten[i] = malloc(Zeile*sizeof(int));

    srand(time(NULL));


//Array mit zufallsdaten ausgeben
    for(i=0; i<Spalte; i++)
        for(a=0; a<Zeile; a++)
        {
            Daten[i][a] = rand()%100;
            printf("Daten[%d][%d] = %2d\n", i, a, Daten[i][a]);
        }

// Hier habe ich keine Ahnung wie ich das Array übergeben soll :D
    ArrayAusgabe(**Daten, Spalte, Zeile);

    free(Daten);
}
 
Zuletzt bearbeitet:
außerdem ist es in C geschrieben
Ok, dann fallen std::array und std::vector als Möglichkeit weg.

Zu den Arraytypen
Bei mehrdim. Arrays gibt es im Wesentliche zwei Arten:

a) Pointerarray, so wie deins:
Im Speicher ist das im Wesentlichen ein eindimensionales "Ober"array, mit Speicheradressen als Werte. Jede Adresse ist der Ort eines "Unter"arrays, wo dann die wirklichen Werte drin sind. (bzw., es kann noch weiter verschachtelt sein, bei 3+ Dimensionen). Die Unterarrays sind alle voneinander unabhängig.

Um auf meinArray[x][y] zuzugreifen wird zuerst die x-te Adresse vom Oberarray genommen, und dann im entsprechenden Unterarray der y-te Wert.

Man sieht die Struktur auch bei dir im Code beim Anlegen: Zuerst ein malloc fürs Oberarray, und dann in einer Schleife eins pro Unterarray.

Vorteile verglichen zum anderen Array (das unten noch beschrieben wird):
a) Jede Dimensionsgröße ist dynamisch (beim anderen ist nur das Oberarray beliebig groß).
b) ei dir zwar nicht der Fall, aber die Unterarrays vom selben Oberarray können auch unterschiedlich groß sein. Also nicht nur wie bei dir 3*3 = 3+3+3 = 9 Werte insgesamt, sondern auch zB. 1+2+3 geht.

Nachteil:
Anlegen vom Array ist komplizierter (beim Anderen braucht man kein malloc in einer Schleife usw.).

b) Einblockarray (keine Ahnung, was ein besseres Wort wäre).
Für ein zweidim. Array, Größe [3][3], gibt es im Speicher ein einziges 9-werte-großes Array. Bei Zugriffen auf Wert [x][y] wird aus x udn y der dazugehörende eindimensionale Index, für das 9-Array, ausgrechnet, und der Wert dann eben genommen. (Prinzipiell sind auch nicht-dynamische mehrdim. Arrays so aufgebaut, hier aber egal).

Nachteil, wie schon gesagt, nur die erste Dimension (hier x) ist dynamisch. y muss fix sein.
Dafür ist das Anlegen einfacher (nur ein einziges malloc).

Zwei Fehler im Code:

Statt
C:
Daten = malloc(Spalte * sizeof(int));
beim Oberarray (nur bei dem) muss
C:
Daten = malloc(Spalte * sizeof(int *));
stehen. Das Oberarray besteht ja nicht aus int's, sondern eben Pointern.
Je nach Compiler und Gerät funktioniert es zwar so auch (wenn int gleich viel Byte wie ein Pointer braucht, und auch in einigen anderen Punkte gleich ist), aber man sollte Programme im Idealfall nicht nur für bestimmte Compiler etc. schreiben.

Und so, wie die Unterarrays mit malloc angelegt werden, müssen sie auch wieder freigegeben werden.
C:
Daten = malloc(Spalte*sizeof(int*));

for(i=0; i<Spalte; i++)
    Daten[i] = malloc(Zeile*sizeof(int));

...

for(i=0; i<Spalte; i++) /*das hier ist neu*/
    free(Daten[i]);     /*das hier ist neu*/

free(daten);

Die Arrayübergabe selber:
Ganz unspannend:
C:
ArrayAusgabe(Daten, Spalte, Zeile);
Einfach ohne Sterne oder irgendwas.
Das ist alles, wirklich :)

Noch zwei Hinweise:
In der Funktion sollten bei a<3 und i<3 die übergebenen Arraygrößen statt 3 verwendet werden.

Und wenn man das Array in der Funktion sicher nicht ändern will, und vor "int ** Daten" bei der Funktion ein "const" stellt, also "const int** Daten", dann prüft der Compiler auch mit, ob man das Array nicht versehentlich doch irgendwo im Code verändert. (const hat noch weitere Vorteile, vor allem in C++, aber hier nicht relevant)
 
Zuletzt bearbeitet:
Lol.... Habe es grade ausprobiert und es Funktioniert wirklich, ganz ohne Sterne :D
Hätte ich echt nicht gedacht, dass es dann doch so einfach ist... Aber jetzt Funktioniert es :p


Nochmal vielen Dank! :)
 
Zurück