Binärdaten unbestimmter Größe einlesen



  • Ich hab mir den Code nochmal durchgeschaut, aber leider keinen Fehler gefunden. Die einzige Möglichkeit bei der ich den Fehler noch vermute ist eine Klassentemplate:

    template<class T>
    class auto_array {
        private:
            T* array;
            mutable bool isReleased;
        public:
            explicit auto_array(T* array_ = NULL) :
                array(array_), isReleased(false)
            {
            }
    
            auto_array(const auto_array<T> &aarray)
            {
                array = aarray.array;
                isReleased = aarray.isReleased;
                aarray.isReleased = true;
            }
    
            ~auto_array()
            {
                if (!isReleased && array != NULL) {
                    delete[] array;
                }
            }
    
            T* get() const
            {
                return array;
            }
    
            T &operator*() const
            {
                return *array;
            }
    
            void operator=(const auto_array<T> &aarray)
            {
                if (!isReleased && array != NULL) {
                    delete[] array;
                }
                array = aarray.array;
                isReleased = aarray.isReleased;
                aarray.isReleased = true;
            }
    
            T* operator->() const
            {
                return array;
            }
    
            T* release()
            {
                isReleased = true;
                return array;
            }
    
            void reset(T* array_ = NULL)
            {
                if (!isReleased && array != NULL) {
                    delete[] array;
                }
                array = array_;
            }
    
            T* operator+(int i)
            {
                return array + i;
            }
    
            T &operator[](int i)
            {
                return array[i];
            }
    };
    

    Codeauszug der C++-Library:

    unsigned short numVerts = toUShort(buffer);
    auto_array<float> verts(new float[2 * numVerts]);
    float* verts2 = verts.get();
    for (int j = 0; j < numVerts; j++) {
        input.read(buffer, 2);
        verts2[2 * j] = scale * ((int) toUShort(buffer) - 32768);
        input.read(buffer, 2);
        verts2[2 * j + 1] = scale * ((int) toUShort(buffer) - 32768);
    }
    

    Mein Code:

    float *verts;
    unsigned short numVerts;
    // ...
    numVerts = toUShort(buffer);
    {
        float vertsTmp[2 * numVerts];
        verts = vertsTmp;
        for (j = 0; j < numVerts; ++j) {
            Text3D_readFile(f, buffer, 2);
            verts[2 * j] = scale * ((int) (toUShort(buffer) - BYTES_15));
            Text3D_readFile(f, buffer, 2);
            verts[2 * j + 1] = scale * ((int) (toUShort(buffer) - BYTES_15));
        }
    }
    

    Passt das so, oder kann da jemand einen Fehler erkennen?



  • ^^wie gross wird 'numVerts'? ist vielleicht zu gross für ein array auf dem stack.
    tip: lass es single-step im debugger laufen und schau dir genau an was passiert, dann findeste bestimmt schnell wo was nicht stimmt.
    🙂



  • Also, ich hab mein Programm und das Tutorialprogramm jetzt mehrmals mit dem Debugger abgesucht und glaube den Fehler jetzt endlich lokalisiert zu haben. Ich glaub, dass ich auch keine Probleme haben sollte ihn zu beseitigen, nur wollte ich nochmal nachfragen, da ich den C++-Quelltext nicht vollständig verstanden habe.

    Erstmal zum Fehler: Die Klasse T3DFont enthält ein Array, das die einzelnen Fontpunkte aufnehmen soll.

    class T3DFont {
        private:
            float spaceWidth;
            float widths[94];
            GLuint displayListId2D;
            GLuint displayListId3D;
        public:
            //Loads the specified font file into a new T3DFont object
            T3DFont(ifstream &input)
            {
                // ...
            }
    }
    

    Meine Struktur sieht ist an sich genau gleich:

    typedef struct _Text3D_ {
        float spaceWidth;
        float widths[94];
        GLuint displayList2D;
        GLuint displayList3D;
    } Text3D;
    

    Im ctor meines Programms wird das Array auch richtig befüllt. Der Unterschied beider Programme ist aber, dass beim TutProg laut eclipseCDT-Debugger ein Array existiert, das nicht nur einen Punkt, sondern auch die anderen drei Variablen beinhaltet. Sozusagen wie wenn ich eine Liste von T3DFont hätte. Diese wird aber beim Aufruf dessen ctor erstellt, was allerdings unlogisch ist:

    T3DFont* font = NULL;
    
    void t3dInit()
    {
        if (font == NULL) {
            ifstream input;
            input.open("charset", istream::binary);
            font = new T3DFont(input);
            input.close();
        }
    }
    

    Hier wird keine Liste angelegt. Die Liste des C++-Programms macht Sinn, ich verstehe deren Allokierung aber nicht. Kann der C++-Compiler hier etwas, das ich nicht weiß? Kann mir hier jemand weiterhelfen?



  • ^^ du musst dir genau ansehen, was dieser konstruktor 'T3DFont(input)' macht.
    das hier:

    T3DFont* font = NULL;
    void t3dInit()
    {
        if (font == NULL) {
            ifstream input;
            input.open("charset", istream::binary);
            font = new T3DFont(input);
            input.close();
        }
    }
    

    wäre in C etwa

    T3DFont* font = NULL;
    ...
    void T3DFont_create_from_file (T3DFont* font, FILE *fp)
    {
       // hier code rein, um den 'font' zu laden
       // und die listen aufzubauen, etc.
       // so wie's der cpp konstruktor macht
       ...
    }
    ...
    void t3dInit()
    {
       if (font == NULL) 
       {
         FILE *fp = fopen ("charset", "rb");
         font = malloc (sizeof(T3DFont));
         T3DFont_create_from_file (font, fp);
         fclose (fp);
       }
    }
    

    🙂



  • Das hatte ich so weit schon. Das Problem ist, dass beim Aufruf des Konstruktors die Liste angelegt wird und nicht erst im Konstruktor. Das ist ja gerade das seltsame. Kann aber auch sein, dass der Debugger mir hier was falsches anzeigt. Werde das jetzt noch mit einem anderen überprüfen. Und den Code schreib ich am besten auch gleich auf die Erstellung einer Liste um. Und gucke dann mal ob es geht...


Anmelden zum Antworten