Übergabe von dynamischem 2-dim. Array
-
mcr schrieb:
Die dynamische Variante, die
du gewählt hast, ist für diese Übergabe ungeeignetJa, das habe ich mir gedacht. Aber wie kann ich sonst ein zweidimensionales Array beliebiger Größe einlesen?
Wie ist die Lösung dieses Problems denn üblich? Ich bin ja sicher nicht der erste der darauf stößt. Legt man dann einfach ein statisches Array von 1000*1000 an und hofft, dass kein Mensch auf die Idee kommt ein so großes Lgs lösen zu wollen?
mfg norfu
und danke schonal für die blitzschnelle antwort!
-
Indem man ein eindimensionales Array mit MxN Elementen (dynamisch) anlegt und darin entsprechend indiziert mit n * M + m (M = Spalten, N = Zeilen; m, n die zugehörigen Indizes).
-
Tachyon schrieb:
Indem man ein eindimensionales Array mit MxN Elementen (dynamisch) anlegt und darin entsprechend indiziert mit n * M + m (M = Spalten, N = Zeilen; m, n die zugehörigen Indizes).
hmmm, okay, das leuchtet ein. allerdings geht mir doch dabei ziemlich die übersichtlichkeit flöten. erst recht bei pivotisierung und co steigt doch dann kein mensch mehr durch den code...aber wenn es tatsächlich die einzig vernünftige lösung sein sollte, muss ich mir den schuh wohl anziehen.
vielen dank!
-
vielleicht lässt sich dafür ein nützliches macro als #define schreiben ?
-
double* matrix; #define Matrix[(x)][(y)] matrix[y*N+x] // N:Spalten
error C2008: '[' : unerwartetes Zeichen in Makrodefinition
-
norfu schrieb:
allerdings geht mir doch dabei ziemlich die übersichtlichkeit flöten.
Das ist richtig. Ich würde sogar noch einen Schritt weiter gehen und behaupten, die Übersichtlichkeit geht dahin, wo es ganz dunkel ist.
Was willst du programmieren, ein Berechnungsprogramm für Finite Elemente, mit 50000*50000 Matrizen ?
Oder darf es ruhig ein bisschen kleiner sein.
In dem Fall dürfte es die meisten Anwender kaum jucken, wenn sie ein paar millisekunden länger auf die Ergebnisse warten.Check this out joe :
#define HastaLaVistaBaby return 1; int main() { const m = 10; // 10 Unbekannte. int i,j; double** mat = malloc( m * sizeof( double* ) ); if ( ! mat ) HastaLaVistaBaby; for ( i = 0; i < m; i++ ) { mat[i] = malloc( m * sizeof( double ) ); if( !mat ) HastaLaVistaBaby; } for ( i = 0; i < m; i++ ) { for ( j = 0; j < m; j++ ) { mat[i][j] = 0.0; } } for ( i = 0; i < m; i++ ) free(mat[i]); free( mat ); return 0; }
-
So wie ich dein Problem verstanden habe, gehen die Einträge der Originalmatrix
bei der Berechnung verloren. Mein Vorschlag (wie schon im ersten Post):Schreib dir eine Funktion, die die Matrix kopiert!
double **copy_mat(double ** mat, int n) { double **res = malloc(n*sizeof(*res)); int i; for (i=0; i<n; ++i) res[i] = memcpy(malloc(n*sizeof(**res)), mat[i], n*sizeof(**res)); return res; } void del_mat(double **mat, int n) { ... } double *getPhi(int n, double **A_orig, double *b) { double **A = copy_mat(A_orig, n); // hier die Berechnung, eventuell ähnlich mit b verfahren del_mat(A, n); return phi; }
Nun arbeitest du auf einer Kopie deiner Matrix, die du nach belieben
verändern kannst. Am Ende wird dann der Speicherbereich mit del_mat
wieder freigegeben.Ich hoffe, ich habe dir damit weiterhelfen können.
Gruß mcr
PS: bitte Korrigiere mich, wenn ich dein Problem nicht richtig verstanden
habe. Danke.
-
mcr schrieb:
for (i=0; i<n; ++i) res[i] = memcpy(malloc(n*sizeof(**res)), mat[i],
Diese Schachtelung ist relativ ... ehm ... 'wagemutig'. Malloc kann durchaus auch mal NULL zurückgeben.
-
No Risk no Fun ? schrieb:
mcr schrieb:
for (i=0; i<n; ++i) res[i] = memcpy(malloc(n*sizeof(**res)), mat[i],
Diese Schachtelung ist relativ ... ehm ... 'wagemutig'. Malloc kann durchaus auch mal NULL zurückgeben.
Stimmt. Man müsste den Code eh noch mit Sicherheitsabfragen versehen.
Du hast Recht, ich hätte die beiden Befehle nicht verschachteln sollen.Gruß mcr
-
mcr schrieb:
So wie ich dein Problem verstanden habe, gehen die Einträge der Originalmatrix
bei der Berechnung verloren. Mein Vorschlag (wie schon im ersten Post):Schreib dir eine Funktion, die die Matrix kopiert!
double **copy_mat(double ** mat, int n) { double **res = malloc(n*sizeof(*res)); int i; for (i=0; i<n; ++i) res[i] = memcpy(malloc(n*sizeof(**res)), mat[i], n*sizeof(**res)); return res; } void del_mat(double **mat, int n) { ... } double *getPhi(int n, double **A_orig, double *b) { double **A = copy_mat(A_orig, n); // hier die Berechnung, eventuell ähnlich mit b verfahren del_mat(A, n); return phi; }
Nur mal so als Frage: Findest Du das so wirklich übersichtlicher, als wenn Du auf ein eindimensionales Array mit berechnetem Index zugreifst? Also ich nicht...
(PS: Sprechende Variablennamen helfen)
-
norfu schrieb:
A = (double**) malloc (sizeof(double*) * n);
Tu' nich malloc casten tun!
Tim hat da mal ein paar Steintafeln vom Berg Sinai geschleppt:
http://www.c-plusplus.net/forum/viewtopic.php?t=206606
-
Tachyon schrieb:
Nur mal so als Frage: Findest Du das so wirklich übersichtlicher, als wenn Du auf ein eindimensionales Array mit berechnetem Index zugreifst? Also ich nicht...
(PS: Sprechende Variablennamen helfen)Jetzt wo du das so pohsten tuhst ...
Matrix[x][y]
versus
Matrix[y*N+x]
... spielt in der Tat eine so große Geige nicht !
-
Jukreizsalbe schrieb:
Tachyon schrieb:
Nur mal so als Frage: Findest Du das so wirklich übersichtlicher, als wenn Du auf ein eindimensionales Array mit berechnetem Index zugreifst? Also ich nicht...
(PS: Sprechende Variablennamen helfen)Jetzt wo du das so pohsten tuhst ...
Matrix[x][y]
versus
Matrix[y*N+x]
... spielt in der Tat eine so große Geige nicht !
Dafür gibt es Whitespaces und die Freiheit, Variablennamen sprechend zu machen:
Matrix[COLUMNS * row + column]
Und man spart sich das unübersichtliche und fehleranfällige allokieren von dynamischen Speicherhappen für jedes Subarray.