C: Pointer auf mehrdimensionale Arrays

Moin,

ich versuche eine Matrix-Transponierung durchzuführen:

ohne Kleinkram sieht das bei mir folgendermaßen aus:

int dim = 10;
double matrixA[dim][dim];
for (m=0; m

jetzt kriege ich die Info "Index benötigt einen Array oder Zeigertyp in der Zeile "matrixC[i][j] = pointerA[j][i];"

Wer kann mir sagen, was mir das sagen soll? :wink:

thx
moe.

(Sorry, Code zitieren ist hier die Pest, und ohne macht der Rest auch keinen großen Sinn…)

pointerA = &matrixA[dim][dim];

Dir ist schon klar, dass du damit einen Zeiger auf den Stack hinter das Ende von matrixA anlegst?

pointerA hat den Typ „double*“. Durch den ersten []-Operator bekommst du ein double, auf das du nicht mehr als Array zugreifen kannst. Versuch es mal mit „double** pointerA“. Außerdem wird dein Code einen langsamen, grausamen Tod sterben, weil der Allokation nach nur ein großes Array existiert, so dass nach der ersten Dereferenzierung mit größter Wahrscheinlichkeit kein gültiger Zeiger da stehen wird. Was du meintest, war:

double \*pointerA[dim];

for( int i=0; i

Außerdem: Mehrdimensionale Arrays sind in dieser Situation aus genau dem Grund nicht wirklich lustig. Du kannst bei einem halbwegs brauchbaren optimierenden Compiler (also mit praktisch jedem spätestens ab der Jahrtausendwende...) ohne große Verluste ein eindimensionales Array kapseln:



    
    double\* Matrix;
    
    /\* eindimensional allokieren wie gehabt \*/
    
    /\* Zweidimensionalen Index in eindimensionalem Array berechnen \*/
    inline int \_mi( int zeile, int spalte ) {
     return zeile\*dim + spalte;
    }
    
    /\* zugriff: \*/
     ...
     double foo = Matrix[\_mi(r,c)];
     ...




Das ist meiner Erfahrung nach nicht wirklich langsamer als der "echte" zweidimensionale Weg, aber vom Standpunkt der Speicherverwaltung aus wesentlich einfacher.

Richtig schön wird es sowieso erst mit C++ und ein paar überladenen Operatoren.

hallo FlamingMoe,

Mit der Zeile

pointerA = &matrixA[dim][dim];

machst Du offensichtlich ein Speicherleck, nach dem ja „pointerA“ soeben allokiert wurde. Die Adresse, die Du soeben gekriegt hast, geht dann auf nimmer wiedersehen verloren.

Nicos hat schon recht: mache ein einfaches Array, das ist viel bequemer. Indizieren kannst Du ja dann auch so:

pointerA[zeile \* spalte] = 0;

lg
Martin

(Sorry, Code zitieren ist hier die Pest, und ohne macht der
Rest auch keinen großen Sinn…)

Was meinst Du ?

pointerA = &matrixA[dim][dim];

Dir ist schon klar, dass du damit einen Zeiger auf den Stack
hinter das Ende von matrixA anlegst?

Jetzt wo Du’s sagst schon. pointerA=&matrixA wäre sinnvoller, oder?

pointerA hat den Typ „double*“. Durch den ersten []-Operator
bekommst du ein double, auf das du nicht mehr als Array
zugreifen kannst. Versuch es mal mit „double** pointerA“.

Werde ich versuchen.

Außerdem wird dein Code einen langsamen, grausamen Tod
sterben, weil der Allokation nach nur ein großes Array
existiert, so dass nach der ersten Dereferenzierung mit
größter Wahrscheinlichkeit kein gültiger Zeiger da stehen
wird.

Ich bin nicht ganz sicher, was das heißt und was ich tun muss, um dieses Problem zu umgehen. Ist nicht jedes mehrdimensionale Datenfeld einfach ein riesig langes Array?

Was du meintest, war:

double *pointerA[dim];

for( int i=0; i

Außerdem: Mehrdimensionale Arrays sind in dieser Situation aus
genau dem Grund nicht wirklich lustig. Du kannst bei einem
halbwegs brauchbaren optimierenden Compiler (also mit
praktisch jedem spätestens ab der Jahrtausendwende…) ohne
große Verluste ein eindimensionales Array kapseln:

double* Matrix;

/* eindimensional allokieren wie gehabt */

/* Zweidimensionalen Index in eindimensionalem Array berechnen
*/
inline int _mi( int zeile, int spalte ) {
return zeile*dim + spalte;
}

/* zugriff: */

double foo = Matrix[_mi(r,c)];

Das ist meiner Erfahrung nach nicht wirklich langsamer als der
„echte“ zweidimensionale Weg, aber vom Standpunkt der
Speicherverwaltung aus wesentlich einfacher.

Klingt gut. Wenn ich die Wahl hätte, würde ich es wohl nach diesem Vorschlag lösen. Leider gibt es schon einige Vorgaben im Programm, und dazu gehört die Struktur der MatrixA. Daran werde ich also nichts ändern können, wenn ich nicht einige hundert Zeilen Quelltext umwerfen möchte. Auf meinem Mist gewachsen ist nur MatrixC, die Pointer und die Transponierung.

Über welchen Ansatz kann ich denn mit Pointern und mehrdimensionalen Arrays arbeiten? Vielleicht kennt jemand eine Seite, wo man das übersichtlich präsentiert bekommt.

Richtig schön wird es sowieso erst mit C++ und ein paar
überladenen Operatoren.

Vielen Dank, aber ich bin auch so schon bedient :wink:

thx
moe.

hallo FlamingMoe,

Mit der Zeile

pointerA = &matrixA[dim][dim];

machst Du offensichtlich ein Speicherleck, nach dem ja
„pointerA“ soeben allokiert wurde. Die Adresse, die Du soeben
gekriegt hast, geht dann auf nimmer wiedersehen verloren.

okay. Also pointerA=&matrixA; damit der Pointer auf das erste (nullte) Array-Element zeigt, richtig? Nur wie kriege ich den Pointer dazu, nach dem er über ++ die erste Dimension durch gegangen ist, in die nächste Dimension zu „springen“?

Über pointerA = pointerA + 1 sollte ich doch von matrixA[0][0] bis matrixA[0][dim-1] kommen richtig? Aber weiter zu matrixA[1][0] komme ich so ja nicht, oder? Oder doch ?? :-?

Nicos hat schon recht: mache ein einfaches Array, das ist viel
bequemer. Indizieren kannst Du ja dann auch so:

pointerA[zeile * spalte] = 0;

Wie auch schon bei Nicos erwähnt, ist der MatrixA-Array leider schon vorgegeben und ich muss damit arbeiten. Mir bleibt nur die Möglichkeit passende Pointer zu basteln. Auch hier nochmal die Bitte, falls jemand eine übersichtliche Seite kennt, die sich mit Pointern auf mehrdimensionale Arrays beschäftigt, mir selbige mitzuteilen :wink:

thx
moe.