Dynamische 2d Arrays zur Laufzeit erstellen
-
Hallo,
ich habe Probleme, während der Laufzeit ein neues 2d Array zu erstellen.
Momentan kann ich ein 1d Array erstellen und dies dann vergrößern. Aber das gelingt mir mit einem 2d Array nicht.Das
new
wie inn C++ kennt ANSI C nicht. Grrrr....
Momentan:
int *XData; XData = (int*) malloc (yDim*sizeof(int)); yDim--; XData = (int*) realloc (XData, yDim*sizeof(int));
Grund dafür ist, dass ich eine Tabelle in ein Array laden will. Ich weiß, beim Programmstart aber noch nicht, wie groß die zu ladende Tabelle ist.
LabWindows/ CVI 7.1.1
Viele Grüsse
Marcel
-
2D-Array erstellen ginge wohl so:
size_t rows=10, columns = 20; int **array = malloc(rows*sizeof(int*)); for (int i=0;i<rows;++i) *(array+i) = malloc(columns*sizeof(int));
-
Grundsaetzlich sind zwei- und mehrdimisionale Arrays keine gute Idee; Zwei Gruende:
- Man muss zunaechst fuer die Pointer und dann fuer die eigentlichen Daten den Speicher allocieren und wieder freigeben
- Der Prozessor muss die Adresse immer berechnen.
Ich arbeite dann mit einem eindimisonalen Array, bei dem ich den Zugriffspunkt berechne:
int GetArrayAccessPoint (int i_xPos, int i_yPos, int iCount_x) { return (i_xPos * iCount_x + i_yPos); }
Das Allocieren und freigeben ist dann trivial:
array = (int *) calloc (iCount_x * iCount_y, sizeof (int)); /*und*/ if (array != NULL) free (array);
-
also ein kleines beispiel fuer einen 2dim array:
/* 2D_dyn_array.c */ #include <stdio.h> #include <stdlib.h> #define BUF 255 int main(void) { int i, j, zeile, spalte; /* Matrix ist Zeiger auf int-Zeiger */ int ** matrix; printf("Wie viele Zeilen : "); scanf("%d", &zeile); printf("Wie viele Spalten: "); scanf("%d", &spalte); /* Speicher reservieren für die int-Zeiger (=zeile) */ matrix = (int **)malloc(zeile * sizeof(int *)); if(NULL == matrix) { printf("Kein Virtueller RAM mehr vorhanden ... !"); return EXIT_FAILURE; } /* Jetzt noch Speicher reservieren für die einzelnen Spalten * der i-ten Zeile */ for(i = 0; i < zeile; i++) { matrix[i] = (int *)malloc(spalte * sizeof(int)); if(NULL == matrix[i]) { printf("Kein Speicher mehr fuer Zeile %d\n",i); return EXIT_FAILURE; } } /* Mit beliebigen Werten initialisieren */ for (i = 0; i < zeile; i++) for (j = 0; j < spalte; j++) matrix[i][j] = i + j; /* matrix[zeile][spalte] */ /* Inhalt der Matrix entsprechend ausgeben */ for (i = 0; i < zeile; i++) { for (j = 0; j < spalte; j++) printf("%d ",matrix[i][j]); printf("\n"); } /* Speicherplatz wieder freigeben * Wichtig! In umgekehrter Reihenfolge */ /* Spalten der i-ten Zeile freigeben */ for(i = 0; i < zeile; i++) free(matrix[i]); /* Jetzt können die leeren Zeilen freigegeben werden */ free(matrix); return EXIT_SUCCESS; }
mehr darueber unter http://www.pronix.de/pronix-625.html
-
Danke für eure Hilfe.
@linuxuser,
Das schaue ich mir jetzt gleich mal an! Danke schon mal.@MBCS-CITP
Da ich das Array nacher in ein 3DGraph laden will, wird deine Methode, soweit ich das beurteilen kann, nicht anwendbar sein.CA_VariantSet2DArray (&vArray, CAVT_DOUBLE, 50, 50, &data); CW3DGraphLib_CWPlot3DPlot3DSimpleSurface (plotHandle, NULL,vArray,CA_DEFAULT_VAL);
@GPC,
Dein Code funktiniert wunderbar.
Doch ein kleines Problem habe ich noch.
Wenn ich die Variablen vor den Befehlszeilen verändere, geht die Sache nicht mehr:So gehts:
int *XData = 0; int rows = 10; int columns = 20; //rows = 10; //columns = 10; int **XData = malloc(rows*sizeof(int*)); for (i=0;i<rows;++i) *(XData+i) = malloc(columns*sizeof(int));
Und so nicht:
int *XData = 0; int rows = 10; int columns = 20; rows = 10; columns = 10; 72: int **XData = malloc(rows*sizeof(int*)); 73: for (i=0;i<rows;++i) 74: *(XData+i) = malloc(columns*sizeof(int));
Fehler:
Bsource.c - 5 errors
72, 1 Illegal statement termination.
72, 13 Type error: pointer expected.
72, 40 Operands of = have illegal types 'int' and 'pointer to void'.
74, 43 Operands of = have illegal types 'int' and 'pointer to void'.
103, 48 Operands of = have illegal types 'int' and 'pointer to int'.Könnte von mir ja ein ganz dummer Fehler sein, sry.
-
wie gesagt unter
http://www.pronix.de/pronix-625.html
wird genau dieses beschrieben!
programmieren beinhaltet leider auch das lesen!
-
Vielen Dank an euch alle.
Besonders an --linuxuser--!
Mein Proggy läuft erstmal!
THSD THX!
-
Vendor2k schrieb:
Könnte von mir ja ein ganz dummer Fehler sein, sry.
War es nicht so, dass bei C alle Variablen am Anfang der Funktion deklariert werden müssen?
Die Zuweisung zwischen drin, dürfte das Problem sein.
-
die "zuweisung zwischendrin" wuerde der compiler schon abweisen, wenns denn illegal ist.
-
Aber was war denn dann das Problem des anderen Codes?
Bis auf die Zuweisungen war doch alles gleich, oder?
-
Das mit den Anweisungen verstehe ich auch nicht.
Das ist aber, glaube ich, mit jeder Variablenzuweisung so. Nicht nur die x und y.
Eine andere Frage:
Die zwei Arrays sind jetzt schon anders.
Wenn ich das DIng am Anfang fest definiere
Array[8][9]dann zeigt mir die Watch das auch als solches an.
Bei der nachträglichen Änderung wird das Array als Array double ** angezeigt.
Die Funktion zur übernahme der Daten unterstützt nun dieses Array nicht mehr.
Kann ich das was mit eine anderen Zeiger zuweisung machen???
-
Vendor2k schrieb:
Wenn ich das DIng am Anfang fest definiere
Array[8][9]dann zeigt mir die Watch das auch als solches an.
Bei der nachträglichen Änderung wird das Array als Array double ** angezeigt.
Liegt daran, dass Array im ersten Fall ein Array ist und im zweiten Fall ein Pointer.
-
hehejo schrieb:
War es nicht so, dass bei C alle Variablen am Anfang der Funktion deklariert werden müssen?
Jo, aber nur bei C89. Außerdem hat das nichts mit Zuweisungen zu tun.
hehejo schrieb:
Aber was war denn dann das Problem des anderen Codes?
Bis auf die Zuweisungen war doch alles gleich, oder?Eigentlich sind beide Listings shit, denn zuerst wird ein int pointer namens XData definiert, und ein paar Zeilen drunter wird ein int Pointer auf int Pointer namens XData (wiedermal) definiert. Die Zuweisungen sind völlig legal. Wäre ja wohl ein Witz wenn ich nicht mitten in der Funktion meinen Variablen was zuweisen könnnte.
Und so geht's wirklich:
int **XData = 0; int rows = 10; int columns = 20; int i=0; XData = malloc(rows*sizeof(int*)); for ( ;i<rows;++i) *(XData+i) = malloc(columns*sizeof(int));
EDIT: Tippfehler
EDIT2: Fehler korrigiert
-
@GPC
Ich glaub du hast noch einen Tippfehler drin. Schau dir mal an auf was du bei deinem ersten malloc() zuweist ;).
-
AJ schrieb:
@GPC
Ich glaub du hast noch einen Tippfehler drin. Schau dir mal an auf was du bei deinem ersten malloc() zuweist ;).Ach mensch, du musstest es jetzt ja sehen...