|
![ein Kapitel weiter](../weiter.gif)
Sicherlich gibt es mehrer Wege um ein 2 Dimensionales Array dynamisch
zu machen. Zwei davon will ich Ihnen zeigen.
1.Weg:
Wir Reservieren erst mal einen ganzen Block Speicher. Wie sieht unsere
(Pseudo)Rechenformel dabei aus.......
dimension1*dimension2*sizeof(**array)
Damit haben wir aber nur einen ganzen Block von Speicher reserviert.
Auf diesen können wir noch nicht mittels array[1][2] zugreifen.
Wir müssen also noch für jede Spalte noch eine Adresse verteilen, wo
die neue Reihe beginnt. Dies geschieht nach erfolgreich reservierten
Speicher mittels......
for(row=0,pointer=(int *)array_2d+x;row<x;row++,pointer+=y)
array_2d[row]=pointer;
Wollen wir uns den Quellcode dazu ansehen.......
/*Download:arr2d.c*/
#include <stdio.h>
int **malloc_2D(size_t x, size_t y) {
int **array_2d; int *p; size_t row;
array_2d=malloc(x*y*sizeof(**array_2d)); if(array_2d == NULL) return NULL; else {
for(row=0, p=(int *)array_2d+x; row<x; row++, p+=y) array_2d[row]=p; } return array_2d; }
int main() {
int **array; int i, j, total=0, row=4, col=7;
array=malloc_2D(row,col); if(array==NULL) {
fprintf(stderr, "Kein Speicher für das 2D-Array bekommen......\n"); exit(0); }
for(i=0; i<row; i++) for(j=0; j<col; j++) array[i][j]=i+j;
for(i=0; i<row; i++) for(j=0; j<col; j++) printf("array[%d][%d]=%d\n",i,j,array[i][j]);
return 0; }
|
Wollen wir uns diesen Vorgang mal Bildlich anhand eines 3x3 Arrays.....
![Zweidimensionales dynamisches Array](malloc3.png)
Der Nachteil an diesem Beispiel ist die schwerere Lesbarkeit des Quellcodes.
Der Vorteil ist, das diese Methode die schnellste ist, mehrdimensionalen
Arrays Speicher zu reservieren.
2.Weg:
Der 2.Weg ist der einfachere, aber auch wieder der langsamere, da
wir für jede Dimension Speicherplatz reservieren. Für die erste
Dimension nicht schlimm, da dies einmalig geschieht. Bei der 2.Dimension
wird aber für jede Reihe Speicherplatz reserviert. Dies bedeutet zum
Beispiel bei einem geforderten Array von [5][5] das 6 mal mit malloc,
ein Speicherplatz reserviert werden muss. 1 mal für die erste Dimension
und für jede Reihe der 2. Dimension wieder. Also einmal 1.Dimension
und fünfmal 2.Dimension. Hierzu nun der Quellcode an dem nur die
Funktion geändert wurde.....
/*Download:arr2d2.c*/
#include <stdio.h>
int **malloc_2D(size_t x, size_t y) {
int **array_2d=NULL; int a;
array_2d=malloc(x*sizeof(*array_2d)); for(a=0; a<x; a++) array_2d[a]=malloc(y*sizeof(*array_2d));
return array_2d; }
int main() {
int **array; int i, j, total=0, row=4, col=7;
array=malloc_2D(row,col); if(array==NULL) {
fprintf(stderr, "Kein Speicher für das 2D-Array bekommen......\n"); exit(0); }
for(i=0; i<row; i++) for(j=0; j<col; j++) array[i][j]=i+j;
for(i=0; i<row; i++) for(j=0; j<col; j++) printf("array[%d][%d]=%d\n",i,j,array[i][j]);
return 0; }
|
Ich glaube anhand diesem Beispiels dürfte dir Grafische Darstellung oben
deutlicher werden.
In unseren Beispielen bisher, haben wir immer nur einmalig dynamischen
Speicherplatz reserviert.
Unser nächstes Ziel soll es sein, erneut Speicherplatz für ein
Zweidimensionales Array zu reservieren. Also immer wenn wir Speicherplatz
benötigen. Dies machen wir logischerweise mit der Funktion realloc.
Die einzige Schwierigkeit besteht darin, herauszufinden ob wir wirklich
neuen Speicherplatz benötigen. Wir brauchen nur den Speicher Blockweise überprüfen...
neudimension1*neudimension2*sizeof(**newarray) >
altdimension1*altdimension2*sizeof(**oldarray)
Trifft es also zu das newarray größer als oldarray können wir
Speicherplatz mit realloc dafür allokieren. Falls nicht bekommt
newarray nur die Adresse von oldarray. Hierzu nun der Quellcode...
/*Download:arr2d3.c*/
#include <stdio.h>
int **realloc_2D(int **old_2d_array, size_t xalt, size_t yalt, size_t xneu, size_t yneu) {
int **neu_2d_array; int *p; size_t row;
/*Benötigen wir Speicherplatz?..........*/ if( xneu*yneu*sizeof(**neu_2d_array)> xalt*yalt*sizeof(**old_2d_array)) /*Wir reservieren Speicher........*/ neu_2d_array=realloc(old_2d_array, xneu*yneu*sizeof(**neu_2d_array));
else neu_2d_array=old_2d_array;
if(neu_2d_array == NULL) return NULL; else {
for(row=xalt, p=(int *)neu_2d_array+xneu; row<xneu; row++, p+=yneu) neu_2d_array[row]=p; }
return neu_2d_array; }
int **malloc_2D(size_t x, size_t y) {
int **array_2d; int *p; size_t row;
array_2d=malloc(x*y*sizeof(**array_2d)); if(array_2d == NULL) return NULL; else {
for(row=0, p=(int *)array_2d+x; row<x; row++, p+=y) array_2d[row]=p; } return array_2d; }
int main() {
int **array; int i, j, total=0, row=4, col=7; int morerow=4, morecol=12; int value1=111; int value2=333;
array=malloc_2D(row,col); if(array==NULL) {
fprintf(stderr, "Kein Speicher für das 2D-Array bekommen......\n"); exit(0); }
for(i=0; i<row; i++) for(j=0; j<col; j++) array[i][j]=value1;
array=realloc_2D(array,row,col,morerow,morecol); if(array==NULL) {
fprintf(stderr, "Kein Speicher für das 2D-Array bekommen......\n"); exit(0); }
for(i=0; i<morerow; i++) for(j=col; j<morecol; j++) array[i][j]=value2;
for(i=0; i<morerow; i++) for(j=0; j<morecol; j++) printf("array[%d][%d]=%d\n",i,j,array[i][j]);
return 0; }
|
Das Problem bei diesem Programm ist das durch erneutes allokieren von
Speicher bleibt häufig der Inhalt des Arrays nicht unberührt. Aber
für Demonstrationszwecken reicht diese Beispiel völlig aus.
Natürlich wäre es auch möglich ein drei,-vier oder fünfdimensionales
dynamisches Array zu erzeugen. Nur stellt sich hier die Frage nach dem Sinn?
Daher nur für Demonstrationszwecken eine Funktion zur dynamischen Reservierung
eines Vierdimensionales Array.........
/*4D-Array*/
int ****malloc_4D(size_t d1, size_t d2, size_t d3, size_t d4) {
int ****array_4d=NULL; int a,b,c;
array_2d=malloc(d1*sizeof(*array_2d)); for(a=0; a<d1; a++){
array_2d[a]=malloc(d2*sizeof(*array_2d[0])); for(b=0; b<d2; b++){
array_2d[a][b]=malloc(d3*sizeof(*array_2d[0][0])); for(c=0; c<d3; d3++){
array_2d[a][b][c]=malloc(d4*sizeof(*array_2d[0][0][0])); } } } return array_4d; }
|
Ich hoffe das ich Ihnen mit diesem Kapitel, ein wenig weiter geholfen habe,
was das Thema betrifft. Vorschläge, Verbesserungen und weitere Codebeispiele
sind immer gerne gesehen.
![ein Kapitel weiter](../weiter.gif)
© 2001,2002 Jürgen Wolf
|