ein Kapitel zurück                                           ein Kapitel weiter

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


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 zurück          nach oben           ein Kapitel weiter


© 2001,2002 Jürgen Wolf