Problem mit Arrayinitialisierung



  • Hallo!
    Ich habe ein Problem, ein Array zu deklarieren, dessen Grenzen zur Compilezeit noch nicht bekannt sind, der Code sieht folgendermaßen aus:

    int xdims = xPoints.size(); //xPoints, yPoints sind vom typ vector<float>
    int ydims = yPoints.size();
    
    float *Coordinates = new float [3][xdims*ydims];
    

    Der Compiler sagt: "error C2540: Kein konstanter Ausdruck als Arraygrenze
    error C2440: 'Initialisierung': 'float (*)[1]' kann nicht in 'float *' konvertiert werden
    Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat."

    Dann geht es weiter mit einer Zuweisung:

    int jj=0;
    for(int i=0; i<ydims; i++)
    	{for(int j=0; j<xdims ; j++)
    		{ Coordinates[0][jj] = xPoints[j];
    		  Coordinates[1][jj] = yPoints[i];
    		  Coordinates[2][jj] = 0;
    		  jj++;
    		}//for(int j
    	}//for(int i
    

    Fehlermeldung(en): "error C2109: Index erfordert ein Array oder einen Zeigertyp"

    Was kann ich denn da tun, damit das so funktioniert, wie ich mir das vorstelle?

    thx,
    Isomorphismus



  • gebrauche Klassen oder ähnliches:

    typedef float Coordinate[3];
    Coordinate *coordinates = new Coordinate[xdims*ydims];
    

    beachte: zugriff auf x-,y- und z-Wert über den 2.Index-Operator:

    Coordinates[jj][0] = xPoints[j];
    Coordinates[jj][1] = yPoints[i];
    Coordinates[jj][2] = 0;
    

    weiter:
    das dynamische array kann auch durch std::vector ersetzt werden.



  • Zweidimensionale dynamische Arrays sind komplizierter zu handhaben. Sie werden als Zeiger auf Zeiger aufgefasst.

    float** Coordinates; // Doppelzeiger
    Coordinates = new float*[3]; // 1. Dimension repräsentiert Zeiger auf die einzelnen Elemente der 2. Dimension
    for (int i = 0; i < 3; ++i)  // 2. Dimension: Elemente einzeln initialisieren
        Coordinates[i] = new float[xdims*ydims];
    

    Und in umgekehrter Reihenfolge wieder mit delete[] freigeben.



  • hm... hab das konzept evtl falsch erkannt.





  • Benutz einfach std::vector

    und dann:

    using namespace std;
    
    // Dopelten Vector anlegen
    vector<vector<float>> array;
    
    for(int x = 0; x < xdims; ++x)
      for(int y = 0; y < ydims; ++y)
        // Zuweisung
        array[x][y] = ...
    

    Oder wie du das da mit deiner "3" machen willst...



  • DataByte schrieb:

    und dann:

    Vor dem Zugriff auf die Indizes wäre das Bereitstellen von Speicher noch eine gute Idee 🙂

    using namespace std;
    
    // Dopelten Vector anlegen
    vector<vector<float>> array;
    array.resize(xdims);
    
    for(int x = 0; x < xdims; ++x) {
      array[x].resize(ydims);
      for(int y = 0; y < ydims; ++y)
        // Zuweisung
        array[x][y] = ...
    }
    


  • LordJaxom schrieb:

    DataByte schrieb:

    und dann:

    Vor dem Zugriff auf die Indizes wäre das Bereitstellen von Speicher noch eine gute Idee 🙂

    using namespace std;
    
    // Dopelten Vector anlegen
    vector<vector<float>> array;
    array.resize(xdims);
    
    for(int x = 0; x < xdims; ++x) {
      array[x].resize(ydims);
      for(int y = 0; y < ydims; ++y)
        // Zuweisung
        array[x][y] = ...
    }
    

    Jop das währe noch eine optimiertere variante..



  • DataByte schrieb:

    Jop das währe noch eine optimiertere variante..

    Das wäre vor allem eine korrekte Variante. Der Zugriff auf ein Vectorelement, welches nicht existiert, ist undefiniert!


  • Mod

    boost::multi_array<float,2> arr(boost::extents[xdims][ydims]);
    // Zugriff
    arr[x][y]=...
    

    Einfach, effizient und im Gegensatz zu allen anderen Lösungen bilden die Daten tatsächlich ein zusammenhängendes Objekt.


Anmelden zum Antworten