Länge Zeiger Array bestimmen



  • @1310-Logik:

    Was Maxi meint, so wie Du es beschreibst funktioniert es nur mit Arrays, nicht mit Zeigern (den Unterschied haben wir imho schon öfters durchgekaut 😉 )

    Also es geht schief, so bald Du den mit [] definierten Array einem mit * definiertem Zeiger zuweist oder übergibst. Denn ein Zeiger ist immer (Adressbusbreite) Bits groß.



  • Ist sowas denn noch C++?
    Ich dachte das Zeiger-Array-Memset Zeugs wär irgendwie C?
    Sowas wie Camper's Klasse ist doch C++, oder?



  • Ja, aber meine (und auch Deine erste) Antwort gingen vom OP aus.



  • 🙂

    ..und ich dachte immer C++ - C == OOP 😉



  • ja danke erstmal für die Antworten, aber das verwirrt mich jetzt schon...

    Was geht den nun und was nicht?

    @camper
    Die Klasse Matrix2d sieht schonmal gut aus.
    Aber der Inhalt ist mir an einigen Stellen bissl rätselhaft,
    könntest du das nochmal etwas näher Beschreiben, vll. mit kl. AnwendungsBsp.
    Der teil im private Abschnitt ist mir nicht wirklich klar und auch die anderern nicht 100%.

    Oder sagst mir link hie rim forum wo genau das behandelt wurde

    danke schonmal. 🙂



  • {   // Testblock
    	Matrix2d matrix2d( 5, 5 );
    	std::cout << matrix2d.rows() << std::endl;
    	std::cout << matrix2d.columns() << std::endl;
    	std::cout << matrix2d[3] << std::endl;
    	std::cout << matrix2d[3][3] << std::endl;
    }   // Testblock
    

    💡 😉



  • Hi!

    Machs so 😃

    void *operator new[]( size_t size )
    {
    	size_t *p = ( size_t *)malloc( size+sizeof( size_t ) );
    	*p = size;
    	return p+1;
    }
    
    void operator delete[]( void *ptr )
    {
    	char *p = ( ( char *)ptr-sizeof( size_t ) );
    	free( p );
    }
    
    size_t memsize( void *p )
    {
    	return *( ( size_t *)( ( char *)p-sizeof( size_t ) ) );
    }
    

    grüße 😉



  • ja danke für die Hinweise.

    das mit der Klasse klappt ja erstmal Anwendungsmäßig...auch wenn ich nicht weiss warum*g*
    Würde wirklich gern bissl Erklärung dafür bekommen.
    (kommentiert mir doch einfach mal bitte jeden Zeile was in der Klasse so passiert, wäre perfekt 😉 )
    Die zeile unter dem Construktor ist mir z.B unter anderem ziemlich rästelhaft:

    : columns_( columns ), v_( rows * columns )
    

    auch was im privat-teil steht.
    für was steht eigentlich so richtig size_t...?
    man gibt doch beim konstruktoraufruf keinen Typ an, ist doch eigentlich immer int???
    (verzeiht mir diese primitiven fragen, aber komme eigentlich net aus der c++Richtung
    muss aber aktuell was damit schreiben, geht ja auch bis auf paar Hänger...wenn ich die dann weiss kein problem*g*)

    @David_pb:
    danke, aber wie ist das jetzt anzuwenden*g*?
    Kann ich damit jetzt die länge eines 1D dyn. array bestimmen?
    Geht das auch mit zweidimensionalen arrays?
    Was bedeutet *operator vor dem new?
    warum zeiger auf speicheradresse p+1?
    Folgendes script geht jedenfalls nicht...

    void *operator new[]( size_t size );
    
    int *myarray;
    myarray = (int*)new[](3);
    
    void *operator new[]( size_t size )
    {
        size_t *p = ( size_t *)malloc( size+sizeof( size_t ) );
        *p = size;
        return p+1;
    }
    

    ..danke das ihr dran bleibt am problem 😉



  • Hi!

    : columns_( columns ), v_( rows * columns )
    

    Hierbei handelt es sich um eine Initialisierungsliste, die Objekte columns_ und v_ werden hier initialisiert.

    void *operator new[]( size_t size )
    {
        size_t *p = ( size_t *)malloc( size+sizeof( size_t ) );
        *p = size;
        return p+1;
    }
    
    void operator delete[]( void *ptr )
    {
        char *p = ( ( char *)ptr-sizeof( size_t ) );
        free( p );
    }
    
    size_t memsize( void *p )
    {
        return *( ( size_t *)( ( char *)p-sizeof( size_t ) ) );
    }
    
    int main()
    {
    	int *myarray = new int[ 20 ];
    	std::cout << "myarray hat: " << ( memsize( myarray ) / sizeof( int ) ) << " Eintraege" << std::endl;
    	delete [] myarray;
    
    	std::cin.get();
    	return 0;
    }
    

    Geht doch! 😃



  • @david_pb:
    ja ok na supi wenn ich doch noch bei meinen alten Arrays bleiben könnte 😉
    Aber ich sehe keine Möglichkeit das, so wie du es machst, bei zweidimensionalen Arrays zu machen, also die zeiger auf zeiger arrays(siehe ganz anfang beitrag).

    Könntest du das kurz beschreiben wie's gehen könnte? 😕
    hmm, und noch die Frage sag mal wenn ich doch mit der Array-Klasse arbeite...wie lässt sich so ein Ding wieder löschen???
    habe folgenden Code, aber ich kann das myarray nicht nochmal erstellen,
    obwohl es ja eigentlich durch den Standardkonstruktor gelöscht sein müsste.

    Matrix2d array(100,10);
        array[0][0] = 111;  // nur so ne sinnlose zuweisung *g*
        array.~Matrix2d();   // array wird komplett gelöscht? k.a.?
        Matrix2d array(1000,400);  // hier schreit der compiler das es nicht geht
       // da der Name schon vergeben sein soll?
    

    Ach ja und lässt sich eigentlich das Klassen-Array auch mit AnsiStrings füllen statt mit int-Werten??
    das ist eigentlich der Inhalt der da rein muss*g*
    danke schonmal 🙂



  • Du solltest den Destructor nicht explicit aufrufen.
    Entweder legst du ein neues Objekt an,

    Matrix2d array(100,10);
        array[0][0] = 111;  // nur so ne sinnlose zuweisung *g*
     //   array.~Matrix2d();  Nein!
        Matrix2d array2(1000,400);  //neuer Name neues Glück
    

    Oder

    {   // Blockanfang
        Matrix2d array(100,10);
        array[0][0] = 111;  // nur so ne sinnlose zuweisung *g*
    }  // Blockende: array wird vom Stack gelöscht
    {   // Blockanfang: Das selbe nochmal
        Matrix2d array(1000,400);
        array[0][0] = 222;  // nur so ne sinnlose zuweisung *g*
    }  // Blockende: array wird vom Stack gelöscht
    

    Nich so schön, aber geht auch 😉

    Oder dynamisch auf den Heap

    Matrix2d* array;   // Lege einen Zeiger an
    array = new Matrix2d(100,10);   // Ertselle dynamisch das Objekt
    // tu was damit
    delete array;         // Lösche das Objekt ( nicht den Zeiger )
    //...
    array = new Matrix2d(1000,40);   // Ertselle dynamisch ein neues Objekt
    // tu was damit
    delete array;         // Lösche das Objekt wieder
    

    Edit: Ach ja, füllen kannst Du mit was Du willst, musst nur den Typ des Vectors, und die Übergabeparameter anpassen. Ev. auch ein template machen, dann kannste das Gerüst wiederverwenden für jeden Typ.
    Edit2: (C)Camper

    class Matrix2d
    {
    public:
        Matrix2d(std::size_t rows, std::size_t columns)
            : columns_( columns ), v_( rows * columns )
        {}
        std::size_t rows()    const { return v_.size() / columns_; }
        std::size_t columns() const { return columns_; }
        AnsiString*       operator[](size_t row)       { return &v_[ row * columns_ ]; }
        const AnsiString* operator[](size_t row) const { return &v_[ row * columns_ ]; }
    private:
        std::size_t columns_;
        std::vector<AnsiString> v_;
    };
    

    Oder als Template

    template<typename T>
    class Matrix2d
    {
    public:
        Matrix2d(std::size_t rows, std::size_t columns)
            : columns_( columns ), v_( rows * columns )
        {}
        std::size_t rows()    const { return v_.size() / columns_; }
        std::size_t columns() const { return columns_; }
        T*       operator[](size_t row)       { return &v_[ row * columns_ ]; }
        const T* operator[](size_t row) const { return &v_[ row * columns_ ]; }
    private:
        std::size_t columns_;
        std::vector<T> v_;
    };
    
    // Instanzierung:
    Matrix2d<AnsiString> ansi_array(100,10);
    Matrix2d<int> integer_array(1000,400);
    


  • @Greenfreek zur Klarstellung:

    In C und auch in C++ gibt es keine Möglichkeit, die Größe eines
    Arrays zur Laufzeit festzustellen.

    Etwas verschärfter formuliert als bereits geschrieben wurde:

    *In C und C++ gibt es kein Sprachkonstrukt Array, wie es
    z.B. in Java (und ich glaube auch in Pascal) existiert.

    Es gibt ausschließlich Zeiger.

    Die Array-Syntax kennt nur der Compiler!*

    Aus diesem Grund wird auch die Länge eines Arrays nirgendwo
    gespeichert und ist auch in keiner Weise zu berechnen.

    Dies ist auch der Grund, warum es ein argc in der main-Funktion gibt
    und alle Strings mit '\0' beendet werden müssen.

    Ich habe den Thread nicht vollständig durchgelesen, aber alle vorgeschlagenen
    Lösungen über Klassen können prinzipiell nichts anderes sein
    als Minimal-Implementierungen von Klassen wie Vector.

    Alles läuft zwangsläufig darauf hinaus, eine Klasse zu entwickeln,
    die durch Kapselung einer Längenangabe und der eigentlichen Daten
    das Konzept eines Arrays simuliert.


Anmelden zum Antworten