Sizeof() gibt falschen Wert aus



  • Ich bin kein C++-Profi, aber ich weiß, wie man sizeof() verwendet und dass das, was mir passiert ist, eingentlich nicht passieren sollte.
    Ich hab in einem Header mehrere Arrays nacheinander deklariert:

    unsigned short array1[]={
    	101,
    	102,
    	};
    
    Uint8 array2[]={
    	2,
    	};
    
    unsigned short array3[]={
    	103,
    	};
    

    Jetzt gibt sizeof(array1) komischerweise den Wert 4. Eine Schleife, die array1 ausliest:

    for(i=0;i<sizeof(array1);i++){
    		tmp=array1[i];
                    cout<<tmp;
            }
    

    Diese Schleife gibt folgende Werte aus:
    101
    102
    2
    103
    103

    Der Compiler scheint die Arrays in einen zusammenzufassen(Da ist noch ein vierter Array, der den Wert 4 beinhaltet). Weiß einer, was ich falsch mache oder wie ich den Fehler beheben kann?



  • arrays können ganz schnell in einen zeiger auf das erste element zerfallen. das passiert z.b. wenn du ein array an eine funkion übergibst. der zeiger hat dann die größe 4, oder auch eine andere, je nach dem, wie groß der zeiger halt ist 😉 . wenn du das verhindern möchtest, benutz einfach std::array, dann hast du solche probleme nicht mehr.
    http://en.cppreference.com/w/cpp/container/array



  • Der Array wird aber nicht übergeben, sondern global deklariert und global genutzt. Außerdem funktioniert es mit anderen Arrays auch, nur nicht damit.



  • CTMN schrieb:

    unsigned short array1[]={
    	101,
    	102,
    	};
    

    Jetzt gibt sizeof(array1) komischerweise den Wert 4

    CTMN schrieb:

    ich weiß, wie man sizeof() verwendet

    Hehe, nein. Nochmal basics bitte, danke.


  • Administrator

    sizeof gibt die Anzahl Bytes zurück. unsigned short ist oft 2 Bytes gross. Du hast 2 Elemente drin. Also gibt sizeof den Wert 4 zurück.

    Insofern, wie "Hi" es gesagt hat, nein, du weisst nicht, wie man sizeof anwendet 😉

    Grüssli



  • Hab grade gelesen, was manche Googlesuchergebnisse für nen Blödsinn ausgeben; ich sollte nur das glauben, was in guten Büchern steht.

    Edit: Bei anderen 2-Byte-Arrays gibt sizeof() ja auch den richtigen Wert zurück.



  • Was man machen kann ist folgendes:

    short arr[] = {1, 2, 3, 4, 5, 6}; // Geht auch fuer int, double etc.
        printf("length(arr) = %d", sizeof(arr) / sizeof(*arr));
    

    Sollte man das so machen? Nein, weil wenn du z.B. das Array an eine Funktion uebergibst, dann funktioniert das bereits nicht mehr.
    Wie schon geschrieben wurde: Verwende in C++ std::array oder std::vector.



  • Ok ihr habt mich überzeugt, ich nehme std::array.



  • size_t size = sizeof( DeinArray ) / sizeof( DeinArray[0] );
    	for( size_t i = 0; i < size; ++i )
    	{...}
    

    So geht das.



  • EOP schrieb:

    So geht das.

    Nein, std::array ist besser.

    Mit rohen Arrays hast du eine fehleranfällige implizite Konvertierung, dafür keine Wertsemantik, keine Debug-Checks und kein STL-konformes Interface. Und du bist nicht einmal schneller.



  • EOP schrieb:

    size_t size = sizeof( DeinArray ) / sizeof( DeinArray[0] );
    	for( size_t i = 0; i < size; ++i )
    	{...}
    

    So geht das.

    Besser std::extent verwenden... 😉



  • int arr[] = { 1, 2, 3, 4, 5 };
    for(auto beg = std::begin(arr); beg != std::end(arr); ++beg)
        std::cout << *beg << '\n';
    

    Oder so.



  • In der Tat, wenn es nur um ein for each geht, dann ist das natürlich noch besser. Oder eben gleich so:

    int arr[] = { 1, 2, 3, 4, 5 };
    for(auto i : arr)
        std::cout << *i << '\n';
    


  • Nexus schrieb:

    EOP schrieb:

    So geht das.

    Nein, std::array ist besser.

    Mit rohen Arrays hast du eine fehleranfällige implizite Konvertierung, dafür keine Wertsemantik, keine Debug-Checks und kein STL-konformes Interface. Und du bist nicht einmal schneller.

    Wenn man std::array hat. Ich z.B. hab's nicht.

    EDIT: oder std::extent oder auto.
    Ich hab alles davon nicht zur Verfügung.



  • std::tr1::array gibts schon seit 2005 und boost::array seit 2000 😉



  • Nexus schrieb:

    std::tr1::array gibts schon seit 2005 und boost::array seit 2000 😉

    Noch was, das ich nicht zur Verfügung hab. 😉



  • und kein STL-konformes Interface

    #include <algorithm>
    #include <iostream>
    
    int main(int argc, char** argv)
    {
        std::for_each(&argv[0], &argv[argc-1], [](char const* c){std::cout << c << "\n";});
    }
    

    hm?



  • Edit: argc-1 ist falsch, müsst argc heißen.


  • Administrator

    EOP schrieb:

    Nexus schrieb:

    std::tr1::array gibts schon seit 2005 und boost::array seit 2000 😉

    Noch was, das ich nicht zur Verfügung hab. 😉

    Du hast kein Inet? Weil sonst könntest du die Array Implementation auch einfach rauskopieren.
    Eine einfache eigene Implementation kann man zudem ganz schnell selber erstellen. Innert 10-15 Minuten hast du so eine Klasse selber geschrieben. Je nach Funktionsumfang sogar noch schneller.

    Grüssli


Anmelden zum Antworten