Typkonvertierungsproblem



  • Hallo!

    Ich verstehe nicht so recht wie ich eine Typkonvertierung von einem void-Zeiger zu einem Zeiger auf Arrays mit z.B. 3 Elementen hinbekommen könnte.

    Also z.B.:

    int (*ptr)[3];
    ptr = (->Typkonv.<-)getVoidPointer();

    Vielen Dank für Tips!



  • Ein Array ist streng genommen auch nur ein Pointer auf das erste Objekt im Array:

    int foo[4];    // foo ist vom Typ int*
    

    Denke, damit bekommst dus hin.



  • Michael E. schrieb:

    foo ist vom Typ int*

    Ist aber nicht ganz richtig.
    z.B. liefert ein sizeof(foo); die Größe des Arrays*die Größe der Typen zurück.



  • Ja, jedoch wollte ich in einer Template-Funktion den Pointer verwenden.
    Da auch die Anzahl an Elementen für die verschiedenen Typen variiert, bräuchte ich einen Zeiger auf n Elemente (eines primitiven Datentyps) und nicht nur einen Zeiger auf das erste Element (eines primitiven Datentyps).



  • Also ich meine dies so:

    int (*ptr)[3];
    ptr = (->Typkonv.<-)getVoidPointer();
    
    Irgendwas(ptr);
    
    template <class ElementType> void Irgendwas(ElementType* ArrayPointer)
    {
       ElementType ArrayPuffer[100];
    
       for(int i=0; i<100; i++)
       {
         ArrayPuffer[i] = *(ArrayPointer+i);
       }
       ...
    }
    


  • template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    


  • sqrt(-1) schrieb:

    int (*ptr)[3];
    ptr = (->Typkonv.<-)getVoidPointer();

    Damit hast Du ein Array von drei Zeigern auf int.

    Eine Typkonvertierung von einem Zeiger in ein Array ist nicht moeglich.

    Wenn Du drei Pointer hast, musst Du jedem getrennt Speicher zuweisen, oder, wenn Du drei Pointer allokieren willst, nimm einen Zeiger auf Zeiger auf int:

    int** ptrptr = new int* [ 3 ];
    for ( int i=0; i<3; ++i ) {
       ptrptr[i] = new int [ 1000 ];
    }
    

    Wie gehabt liefert Dir dann "ptrptr[0]" den ersten Zeiger, "ptrptr[1]", den zweiten Zeiger und "ptrptr[2]" den dritten Zeiger.



  • Das war da ein Fehler von mir.
    Ich brauche ja einen Zeiger vom Typ eines gesammtes (z.B.) int Arrays.
    Geht dies überhaupt oder muss ich da auf eine Struktur ausweichen?



  • Wenn ich dich richtig versteh, dann ist es immer noch sowas:

    template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    


  • Ich will aber nur einen Zeiger übergeben der z.B. vom Typ int[4] ist.

    Also um das Gesammtproblem zu schildern:

    Ich habe fünf void-Zeiger.
    Jeder dieser zeigt auf ein erstes Element.
    Je nach Zeiger ist das Element vom Typ:
    float[3]
    float
    byte[4]
    float[2]
    short

    Nach dem ersten Element kommt nicht gleich das nächste im Speicher, sondern erst nach einer gewissen Anzahl von Bytes.
    Die Anzahl an Elementen ist für alle Zeiger gleich.
    Also:
    float[n][3]
    float[n]
    byte[n][4]
    float[n][2]
    short[n]

    Ich möchte nun alle Elemente dieser Arrays in eine Datei speichern.
    Da ich nicht für jeden Array Typ eine eigene Funktion schreiben sollte, möchte ich eine template Funktion benutzen.

    Tja, die Frage ist nun wie ich dies machen sollte.



  • PS.: Die Arrays sollen einzeln gespeichert werden, also nicht alle auf einmal.



  • template<class T, int i, int j>
    void foo(T bar[i][j])
    {
        ...
    }
    

    😕



  • Noch mal genauer:

    Im Speicher liegen 3xfloat hintereinander.
    Darauf habe ich einen void-Zeiger.
    Dies 3xfloat sind aber nur ein Element.
    Nach n-Bytes kommen wieder 3xfloat.
    Nach 2*n-Bytes kommen wieder 3xfloat.
    Diese Elemente gibt es x mal.

    Das Ganze gibt es nicht nur mit 3xfloat, sonder noch in 4 weiteren Formaten(wie gezeigt) und deren Elementeanzahl ist immer x.

    Eine Template Funktion soll fähig sein alle Elemente des jeweiligen Typs in einer Datei zu speichern.
    Die Frage ist nun wie ich die Typenunterscheidung hinbekomme.

    Danke für all die Mühe! 😉



  • Und um noch einmal zu sagen warum ich glaub das dies nicht hilft:

    Michael E. schrieb:

    Wenn ich dich richtig versteh, dann ist es immer noch sowas:

    template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    

    Hier würde man ja ein Array des Types T erstellen.
    Ich habe aber nur den Zeiger auf das erste Element.
    Und die möglichen Typen auf die der Zeiger zeigt, sind:

    float[3]
    float
    byte[4]
    float[2]
    short



  • Ich versteh immer noch nicht, wieso meine zwei Funktionen nicht helfen. Wie groß ist bei dir n?



  • Michael E. schrieb:

    Ich versteh immer noch nicht, wieso meine zwei Funktionen nicht helfen.

    Ich will an die Template Funktion doch nur einen Zeiger übergeben.
    Der Typ worauf der Zeiger zeigt ist einer von denen:

    float[3]
    float
    byte[4]
    float[2]
    short

    Dein Template-Vorschlag würde bei der Übergabe eines Zeiger aber eine Array von Zeigern als Parameter annehmen, oder?

    Wie groß ist bei dir n?

    Irgend eine Zahl, z.B. 40.



  • Um das eigentliche Problem auf den Nenner zu bringen:

    Wie kann ich am einfachsten einen Zeiger erstellen, der auf ein Objekt z.B. vom Typ float[3] zeigt?

    Denn wenn ich folgendes mache...

    float blah[3];

    ... ist blah ja ein Zeiger auf ein Objekt des Types float, nicht aber float[3] - so wie ich es brauche.

    Wenn ich wie vorgeschlagen folgendes mache:

    template<class T, int i>
    void foo(T bar[i])
    {
        ...
    }
    

    ... ist der Parameter ja ein Array aus i Elementen des Types T.
    Das bringt mir nichts weil ich ja einen Zeiger übergeben will und gleichzeitig den Typ (also z.B. float[3]) für das Template übermitteln muss.



  • sqrt(-1) schrieb:

    Michael E. schrieb:

    Ich versteh immer noch nicht, wieso meine zwei Funktionen nicht helfen.

    Ich will an die Template Funktion doch nur einen Zeiger übergeben.
    Der Typ worauf der Zeiger zeigt ist einer von denen:

    float[3]
    float
    byte[4]
    float[2]
    short

    Dein Template-Vorschlag würde bei der Übergabe eines Zeiger aber eine Array von Zeigern als Parameter annehmen, oder?

    template<class T, int i>
    void foo(T bar[i])    // bekommt ein eindimensionales Array, also sozusagen T*
    {
        ...
    }
    
    template<class T, int i, int j>
    void foo(T bar[i][j])    // erhält ein zweidimensionales Array, also sozusagen T**
    {
        ...
    }
    

    Wie groß ist bei dir n?

    Irgend eine Zahl, z.B. 40.[/quote]
    Damit ist mir nicht geholfen. Ist das irgendeine ganz rein zufällige Zahl? Ich glaub eher nicht.



  • Also es funktioniert z.B. folgendes:

    struct _ElementTypA
    {
      float Element[3];
    }*ElementTypA;
    
    struct _ElementTypB
    {
      float Element;
    }*ElementTypB;
    
    ElementTypA = (_ElementTypA*)getVoidPointer();
    ElementTypB = (_ElementTypB*)getVoidPointer();
    
    schreibeArray(ElementTypA);
    schreibeArray(ElementTypB);
    
    template <class _ElementTyp> void schreibeArray(_ElementTyp* ElementTyp)
    {
       ElementType ArrayPuffer[100];
    
       for(int i=0; i<100; i++)
       {
         ArrayPuffer[i] = *(ArrayPointer+i);
       }
       ...  
    }
    

    Strukturen sind wirken da jedoch ziemlich umständlich.
    Gibt es da nicht etwas "schöneres"?



  • Achja, habe das oben gezeigt nicht getestet, der Compiler nimmt es jedoch an.


Anmelden zum Antworten