Dynamische Arraygröße



  • Hallo, ich bin neu hier im forum und hab direkt die erste frage ^^
    Zu mir:
    Ich bin 15 (fast 16) Jahre alt und wohne in NRW.
    Mit programmieren bin ich vor 2 jahren angefangen mit php websiten zu programmieren und mache das auch jetzt noch zwischendurch sehr gerne.
    Ich programmiere seid fast 1.5 jahren mit c++ (besonders im bereich der spieleprogammierung), kenne mich also ganz gut mit c++ aus, hab aber selten noch kleine schwierigkeiten wie diese.

    Ich weiß echt nicht woran das liegt, ich schreib immer riesen Programme und scheitere dann an irgentwelchem kleinkram, der alles zum stillstehen bringt.
    Also, bevor ich mein problem schildere, möchte ich einmal kurz sagen:
    Wie einige von euch wissen, programmiere ich mein eigenes 2d game engine.
    mitlerweile kann ich auch schon sprites rendern, aber das problem ist dabei die varibale anzahl der sprites.
    Alle sprites sind in einem vector aufgereit, jede sprite besteht aus genau einem vertex (ja nur einen, ich arbeite mit geometrieshadern).

    Zum Problem:

    const int numSprites = spritevec.size()-1;
    vertex verts[numSprites];
    
    for(unsigned int i=0; i<spritevec.size(); i++){
    	verts[i] = spritevec[i]->getAsVertex();
    }
    

    logischer weise ist in diesem code "spritevec.size()-1" kein konstantwert und weil man einen konstantwert brauch um die arraygröße anzugeben, hab ich ein problem. ich kann als vertex-array leider KEINE vectoren verwenden.

    Meine Frage ist also, wie kann ich den vertex-array variable an die größe des spritevec anzupassen.



  • gamer8o4 schrieb:

    ich kann als vertex-array leider KEINE vectoren verwenden.

    Wie kommst du darauf?



  • klappt sons irgentwie nicht, weil ich sie dx10 als pointer auf einen array übergeben muss :S falls einer weiß wie das doch geht, sag bitte bescheid.

    hier mal ein bisschen mehr vom code:

    const int numSprites = spritevec.size()-1;
    	vertex verts[numSprites];
    
    	for(unsigned int i=0; i<spritevec.size(); i++){
    		verts[i] = spritevec[i]->getAsVertex();
    	}
    
    	//create vertex buffer
    	D3D10_SUBRESOURCE_DATA initData;
    	initData.pSysMem = &verts;
    
    	D3D10_BUFFER_DESC bd;
    	bd.Usage = D3D10_USAGE_DEFAULT;
    	bd.ByteWidth = sizeof( vertex ) * (numSprites);
    	bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    	bd.CPUAccessFlags = 0;
    	bd.MiscFlags = 0;
    
    	if ( FAILED( D3DDevice->CreateBuffer( &bd, &initData, &VertexBuffer ) ) ) { MessageBox(NULL, L"Could not update the vertex buffer!", L"Fatal Error", MB_ICONERROR); return; }
    
    	// Set vertex buffer
    	UINT stride = sizeof( vertex );
    	UINT offset = 0;
    	D3DDevice->IASetVertexBuffers( 0, 1, &VertexBuffer, &stride, &offset );
    


  • Einen Zeiger zum ersten Element des Vektors bekommst du mit &verts[0] .
    Die Elemente in einem Vektor folgen im Speicher direkt aufeinander wie in einem normalen Array.



  • also könnte ich einfach den array zu einem vector machen?
    funktioniert aber irgentwie nicht, dann werden die sprites nicht mehr angezeigt

    std::vector<vertex> verts;
    
    	for(unsigned int i=0; i<spritevec.size(); i++){
    		verts.push_back(spritevec[i]->getAsVertex());
    	}
    	//create vertex buffer
    	D3D10_SUBRESOURCE_DATA initData;
    	initData.pSysMem = &verts;
    


  • Vektor != Elemente des Vektors.



  • wie geht es denn richtig, kannst du mir den richtigen code geben?



  • Siehe:

    Einen Zeiger zum ersten Element des Vektors bekommst du mit &verts[0].



  • aber ich brauche doch einen pointer auf alle elemnte (als array)


  • Mod

    gamer8o4 schrieb:

    aber ich brauche doch einen pointer auf alle elemnte (als array)

    Nein, ganz sicher nicht. Das wäre die ungewöhnlichste Bibliothek aller Zeiten. Jetzt kommt wohl der Punkt, an dem man auch als C++-ler mal die Feinheiten von rohen Arrays angucken muss, da man dieses Wissen für die Benutzung von C-Bibliotheken braucht. Dann wirst du sehen, dass der Tipp schon richtig ist.



  • #include <iostream>
    #include <vector>
    
    void schnittstelle(int count, const int* elems)
    {
      for (int i=0; i<count; ++i) {
        std::cout << ' ' << elems[i];
      }
      std::cout << std::endl;
    }
    
    int main()
    {
      std::vector<int> vec;
      vec.push_back(2);
      vec.push_back(7);
      vec.push_back(1);
      vec.push_back(8);
      vec.push_back(2);
      vec.push_back(8);
      vec.push_back(1);
      vec.push_back(8);
      vec.push_back(2);
      vec.push_back(8);
      schnittstelle(vec.size(),vec.empty() ? 0 : &vec[0]);
    }
    

    Das funktioniert, weil der C++ Standard garantiert, dass die Elemente eines std::vector s alle direkt hintereinander im Speicher liegen, so, wie es auch bei einem "normalen Array" der Fall ist.



  • Üblicherweise kann man von eine solchen C-Schnittstelle auch erwarten, dass die bei übergabe einer Größe von 0 den Zeiger nicht anfasst. 🙂



  • Nein, bei mir waere das nicht ueblich. Darueber hinaus fasst die beispielhafte schnittstelle den Zeiger auch nicht bei count == 0 an, d.h. ist die Abfrage vec.empty() ueberfluessig.



  • Verlesen? Genau das habe ich doch gesagt. 😉



  • Das empty ist immer notwending, da &vec[0] ansonsten UB erzeugt.



  • Oder einfach .data() verwenden.



  • 314159265358979 schrieb:

    Üblicherweise kann man von eine solchen C-Schnittstelle auch erwarten, dass die bei übergabe einer Größe von 0 den Zeiger nicht anfasst. 🙂

    Das erwarte ich ja auch. Das Blöde ist nur, dass ich im empty-Fall den operator[] nicht verwenden darf. Hier ist die Abfrage natürlich überflüssig, da genug Elemente im Vektor sind. Aber ich wollte diese Zeile unabhängig vom Befüllen des Vektors haben, so dass das Programm kein UB hervorruft, wenn man die push_back-Zeilen entfernt.



  • 314159265358979 schrieb:

    Oder einfach .data() verwenden.

    data kenne ich bei vector nicht. Ich dachte, das gäb's nur bei std::string & co.





  • pyhax schrieb:

    In C++11 gibt es .data auch bei vectoren.

    Ja, habs auch gerade nochmal nachgeguckt. Aber erst, wie gesagt, ab C++11.


Anmelden zum Antworten