2010-01-24 23 views
8

Ich möchte eine Matrix zuweisen.zuteilen Matrix in C

ist dies die einzige Option:

int** mat = (int**)malloc(rows * sizeof(int*)) 

for (int index=0;index<row;++index) 
{ 
    mat[index] = (int*)malloc(col * sizeof(int)); 
} 
+1

[Wirf das Ergebnis von malloc nicht in C] (http: // stackoverflow.com/q/605845/995714) –

Antwort

20

Nun, Sie nicht geben uns eine vollständige Implementierung. Ich nehme an, dass du es meintest.

int **mat = (int **)malloc(rows * sizeof(int*)); 
for(int i = 0; i < rows; i++) mat[i] = (int *)malloc(cols * sizeof(int)); 

Hier ist eine andere Option:

int *mat = (int *)malloc(rows * cols * sizeof(int)); 

Dann Sie simulieren die Matrix

int offset = i * cols + j; 
// now mat[offset] corresponds to m(i, j) 

für Reihenhauptordnung und

int offset = i + rows * j; 
// not mat[offset] corresponds to m(i, j) 

für column-Haupt Bestellung mit .

Eine dieser beiden Optionen ist eigentlich der bevorzugte Weg, um eine Matrix in C zu handhaben. Dies liegt daran, dass die Matrix jetzt zusammenhängend im Speicher gespeichert wird und Sie von locality of reference profitieren. Grundsätzlich wird der CPU-Cache viel glücklicher mit Ihnen sein.

+1

Wenn Ihr Compiler Arrays mit variabler Länge unterstützt oder wenn 'cols' eine Kompilierzeitkonstante ist, müssen Sie die Offsets nicht einmal selbst berechnen; Wenn Sie 'int (* mat) [Spalten] = malloc (rows * sizeof * mat)' verwenden, können Sie über 'mat [i] [j]' auf die Elemente zugreifen und trotzdem einen zusammenhängenden Speicherblock verwenden. – Christoph

+1

Auch die Leistung wird ignoriert , eine einzelne Zuordnung ist auch vorzuziehen, weil es einfacher ist. Es gibt weniger Dinge, die später freigegeben werden können, und es ist nicht notwendig, sich mit partiellen Zuteilungsfehlern zu befassen. – jamesdlin

+1

Wäre das nicht ein Problem, wenn jeder malloc diskontinuierliche Speicherblöcke erstellt, die ihre Adressen nicht seriell machen? Zum Beispiel könnte das erste malloc den Zeiger 0x635 zurückgeben, und die anderen mallocs könnten die Zeiger 0xA279, 0xB7DD usw. zurückgeben. Wenn dies geschieht, würde eine einfache Berechnung wie oben beschrieben nicht funktionieren. –

2

Wie wäre es einfach:

int* mat = malloc(rows * columns * sizeof(int)); 
2

Sie können auch Calloc verwenden, das zusätzlich die Matrix für Sie initialisiert. Die Signatur ist etwas anders:

int *mat = (int *)calloc(rows * cols, sizeof(int)); 
0

Sie können kollabieren, es zu malloc einem Anruf, aber wenn Sie ein 2D-Array-Stil verwenden möchten, müssen Sie noch die for-Schleife.

int** matrix = (int*)malloc(rows * cols * sizeof(int) + rows * sizeof(int*)); 

for (int i = 0; i < rows; i++) { 
    matrix[i] = matrix + rows * sizeof(int*) + rows * cols * sizeof(int) * i; 
} 

Noch nicht getestet, aber Sie bekommen die Idee. Ansonsten würde ich bei dem bleiben, was Jason vorschlägt.

+0

das funktioniert nur wenn 'sizeof (int) == sizeof (int *)' - sonst ist der Offset falsch; es könnte tatsächlich falsch sein, selbst wenn dies der Fall ist – Christoph

+0

@Christoph: Guter Punkt, und das ist auch einfach zu umgehen, aber wie ich in meiner Antwort darauf hingewiesen habe, ist dies ungeprüft. Das jetzt behoben. –

-1

Für eine n-dimensionalen Arrays können Sie dies tun:

int *matrix = malloc(D1 * D2 * .. * Dn * sizeof(int)); // Di = Size of dimension i 

Um eine Array-Zelle mit der typischen Art und Weise zugreifen, dies zu tun:

int index = 0; 
int curmul = 1; 
int i; 
int indexes = {I1, I2, ..., In}; // Ii = Index in dimension i 

for(i = N-1; i >= 0; i--) { 
    index = index + indexes(i) * curmul; 
    curmul = curmul * Di; 
} 

(Hinweis: nur knapp sein Ziel Test aber jetzt sollte funktionieren.Übersetzt von meinem Matlab-Code, aber in Matlab-Index beginnt von 1, so dass ich einen Fehler gemacht habe (aber ich glaube nicht))

Viel Spaß!

3

, was Sie tun können, ist

int (*mat)[col]; 
mat=(int (*)[col])malloc(sizeof(*mat)*row); 

und dann benutze diese neue Matrix als mat [i] [j]