size_t Overflow erkennen



  • // ... Einlesen von n ...
    unsigned int ergebnis=1;
    for(unsigned int i=0; i<n; ++i) {
        if(ergebnis*2 < ergebnis) { //Overflow
              //Behandlung des overflows ....
        } else {
              ergebnis*=2;
        }
    }
    // In ergebnis steht nun 2^n
    

    ]



  • Etwas umständlich 😉

    size_t x;
    
    if (n > sizeof(size_t)*CHAR_BIT-1)
        // Fehlerfall
        x = 0;
    else
        x = 1<<n;
    


  • sizeof(size_t)*CHAR_BIT-1
    

    ???????????

    was willste mit dieser formel ausdrücken?



  • 31 kommt da etwa raus und das passt !



  • -.- schrieb:

    sizeof(size_t)*CHAR_BIT-1
    

    ???????????

    was willste mit dieser formel ausdrücken?

    sizeof(size_t) gibt mir die Anzahl der Bytes des Typs size_t
    CHAR_BIT gibt mir die Zahl der Bits pro Byte
    Die Multiplikation derer ergibt die Anzahl an Bits im Typ size_t
    1 muss ich noch abziehen, da der Grenzfall n == sizeof(size_t)*CHAR_BIT bereits undefiniert auf die Anweisung 1<<n (entspricht 2^n) wäre

    Klar?


  • Mod

    Tim schrieb:

    sizeof(size_t) gibt mir die Anzahl der Bytes des Typs size_t
    CHAR_BIT gibt mir die Zahl der Bits pro Byte
    Die Multiplikation derer ergibt die Anzahl an Bits im Typ size_t
    1 muss ich noch abziehen, da der Grenzfall n == sizeof(size_t)*CHAR_BIT bereits undefiniert auf die Anweisung 1<<n (entspricht 2^n) wäre

    Klar?

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.
    Und der Ausdruck 1<<n hat auch nur dann den Typ size_t, wenn n diesen Typ hat.
    Für Zwecke wie diese existiert numeric_limits:
    numeric_limits<decltype(1<<n)>::digits liefert das richtige Ergebnis.



  • camper schrieb:

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.

    Kennst du auch nur ein System bei dem das nicht zutrifft?



  • Okay, vielen Dank, das ergibt Sinn. Den <<-Operator kannte ich auch noch nicht, damit erspart man sich die wohl doch sehr langsame power-Funktion (bzw. das Schreiben einer eigenen schnelleren für int-Typen).

    Kurze Frage noch: Ist es eigentlich möglich, einen Array anzulegen, der mehr Einträge hat, als man mit dem Typen size_t darstellen kann? Gibt es nicht irgendwann bei solchen extremen Größen Probleme mit der Adressierung?

    Edit: Kann ich mir überhaupt sicher sein, dass beim Umgang eines Arrays mit max size_t vielen Einträgen (Objekten) alles gut geht (abgesehen davon, dass der physische Speicher recht schnell voll sein wird)?

    Das sind jetzt alles etwas hypothetische Fragen - ich bin halt gerade dabei, einen exponentiellen Algorithmus (Laufzeit und Speicher) zu implementieren, um einfach zu sehen, wie schnell man da an die Grenzen stößt (wohl sehr schnell).



  • plizzz schrieb:

    Kurze Frage noch: Ist es eigentlich möglich, einen Array anzulegen, der mehr Einträge hat, als man mit dem Typen size_t darstellen kann?

    AFAIK nicht, nein.

    Gibt es nicht irgendwann bei solchen extremen Größen Probleme mit der Adressierung?

    Würde es geben. Aus dem Grund ist size_t so gut wie immer sowas wie unsigned int, hat also je nach Betriebssystem auf "normalen" PCs 32 oder 64 bit. Aus dem Grund sind jetzt auch die 64bit Systeme im Kommen, weil man mit 32 bit eben nur <4GB Speicher adressieren kann.

    Edit: Kann ich mir überhaupt sicher sein, dass beim Umgang eines Arrays mit max size_t vielen Einträgen (Objekten) alles gut geht (abgesehen davon, dass der physische Speicher recht schnell voll sein wird)?

    Abgesehen davon dass du so viel Speicher vermutlich nicht wirst anfordern können, kannst du dir sicher sein, dass du damit ganz normal arbeiten kannst, wenn du ihn erstmal hast. Natürlich mit entsprechenden Performanceproblemen...


  • Mod

    plizzz schrieb:

    Kurze Frage noch: Ist es eigentlich möglich, einen Array anzulegen, der mehr Einträge hat, als man mit dem Typen size_t darstellen kann? Gibt es nicht irgendwann bei solchen extremen Größen Probleme mit der Adressierung?

    size_t ist groß genug, um die Größe eines jeden einzelnen Objektes beschreiben zu können, ein Array ist auch so ein Objekt. Die Antwort ist also nein. Es ist allerdings möglich, dass die Gesamtmenge des verfügbaren Speichers nicht in ein size_t passt, dieser Speicher kann dann aber nicht als ein zusammenhängendes Objekt verwendet werden.

    Tim schrieb:

    camper schrieb:

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.

    Kennst du auch nur ein System bei dem das nicht zutrifft?

    Ich hoffe, du beabsichtigst nicht, hier ein Argument anhand meines Wissens oder Nichtwissens anzubringen?



  • Tim schrieb:

    camper schrieb:

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.

    Kennst du auch nur ein System bei dem das nicht zutrifft?

    Irgendwann landet mal ein Alien-Raumschiff auf der Erde und dann hängt die Rettung der Welt davon ab, dass dein C++ Code fehlerfrei auf diesem Raumschiff läut. Auf diesem Raumschiff hat ein Byte 11 Bits und sie verwenden das letzte nicht, aber sie haben einen C++ Compiler.



  • Nicht irgendwann. Noch dieses Jahr. 😮



  • camper schrieb:

    Tim schrieb:

    camper schrieb:

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.

    Kennst du auch nur ein System bei dem das nicht zutrifft?

    Ich hoffe, du beabsichtigst nicht, hier ein Argument anhand meines Wissens oder Nichtwissens anzubringen?

    Es geht mir nicht darum ob du eines kennst, sondern ob es sowas wirklich gibt. Denn ich kenne keines. Und ganz ehrlich, ich sehe es nicht ein so einen konstruierten Fall in SW zu berücksichtigen. Und wenn mal eine Architektur sowas macht, dann soll sie meine SW gar nicht spielen dürfen 😉

    ~**^°#{[< schrieb:

    Tim schrieb:

    camper schrieb:

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.

    Kennst du auch nur ein System bei dem das nicht zutrifft?

    Irgendwann landet mal ein Alien-Raumschiff auf der Erde und dann hängt die Rettung der Welt davon ab, dass dein C++ Code fehlerfrei auf diesem Raumschiff läut. Auf diesem Raumschiff hat ein Byte 11 Bits und sie verwenden das letzte nicht, aber sie haben einen C++ Compiler.

    Systeme mit CHAR_BIT != 8 sind übrigens nicht sooo unüblich.


  • Mod

    Tim schrieb:

    camper schrieb:

    Tim schrieb:

    camper schrieb:

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.

    Kennst du auch nur ein System bei dem das nicht zutrifft?

    Ich hoffe, du beabsichtigst nicht, hier ein Argument anhand meines Wissens oder Nichtwissens anzubringen?

    Es geht mir nicht darum ob du eines kennst, sondern ob es sowas wirklich gibt. Denn ich kenne keines. Und ganz ehrlich, ich sehe es nicht ein so einen konstruierten Fall in SW zu berücksichtigen. Und wenn mal eine Architektur sowas macht, dann soll sie meine SW gar nicht spielen dürfen 😉

    ~**^°#{[< schrieb:

    Tim schrieb:

    camper schrieb:

    Vorausgesetzt, alle Bits von size_t nehmen an der Wert-Repräsentation teil. Das ist zwar wahrscheinlich, aber nicht garantiert.

    Kennst du auch nur ein System bei dem das nicht zutrifft?

    Irgendwann landet mal ein Alien-Raumschiff auf der Erde und dann hängt die Rettung der Welt davon ab, dass dein C++ Code fehlerfrei auf diesem Raumschiff läut. Auf diesem Raumschiff hat ein Byte 11 Bits und sie verwenden das letzte nicht, aber sie haben einen C++ Compiler.

    Systeme mit CHAR_BIT != 8 sind übrigens nicht sooo unüblich.

    Gegen CHAR_BIT ist gar nichts einzuwenden, denn bei char wissen wir, dass Objekt- und Wertrepräsentation übereinstimmen. Die Verwendung sizeof hingegen führt in die Irre, denn dieser Wert bezieht sich eindeutig auf das Objekt und nicht den Wert. Da beide Reoräsentationen (aus gutem Grund) für gewöhnlich übereinstimmen, mag die die sizeof-Variante in einem sehr weit gefassten Sinn "funktionieren". A zu sagen, wenn B gemeint ist, ist trotzdem ein (logischer) Fehler auch dann, wenn zufällig mal A==B gilt.



  • Bei mir kommt dabei die Frage auf: wie lösen die in C das Problem?
    Die haben nunmal nur sizeof.
    Ist in C definiert, dass size_t alle Bits nutzt und in C++ nicht?


  • Mod

    DrakoXP schrieb:

    Bei mir kommt dabei die Frage auf: wie lösen die in C das Problem?
    Die haben nunmal nur sizeof.
    Ist in C definiert, dass size_t alle Bits nutzt und in C++ nicht?

    Es gibt noch SIZE_MAX ... und daraus binäre Stellen zu machen, ist die Aufgabe des Programmierers.



  • DrakoXP schrieb:

    Bei mir kommt dabei die Frage auf: wie lösen die in C das Problem?

    Welches Problem? Das theoretische? Nein, in C lösen wir doch lieber reale 😉



  • pumuckl schrieb:

    plizzz schrieb:

    Kurze Frage noch: Ist es eigentlich möglich, einen Array anzulegen, der mehr Einträge hat, als man mit dem Typen size_t darstellen kann?

    AFAIK nicht, nein.

    Gibt es nicht irgendwann bei solchen extremen Größen Probleme mit der Adressierung?

    Würde es geben. Aus dem Grund ist size_t so gut wie immer sowas wie unsigned int, hat also je nach Betriebssystem auf "normalen" PCs 32 oder 64 bit. Aus dem Grund sind jetzt auch die 64bit Systeme im Kommen, weil man mit 32 bit eben nur <4GB Speicher adressieren kann.

    Edit: Kann ich mir überhaupt sicher sein, dass beim Umgang eines Arrays mit max size_t vielen Einträgen (Objekten) alles gut geht (abgesehen davon, dass der physische Speicher recht schnell voll sein wird)?

    Abgesehen davon dass du so viel Speicher vermutlich nicht wirst anfordern können, kannst du dir sicher sein, dass du damit ganz normal arbeiten kannst, wenn du ihn erstmal hast. Natürlich mit entsprechenden Performanceproblemen...

    Ah okay, das heißt dann also, dass ich insgesamt nur sizeof(size_t) viele Bytes an Speicher überhaupt adressieren kann (ist das die "Definition" von size_t ?)?



  • std::size_t kann schlicht für alle Speichergrößen verwendet werden und ist eigentlich immer exakt so groß, um jedes Byte das der Prozessor addressieren kann auch selbst darstellen könnte. Wären unter 64bit immerhin 16.777.216 Terrabyte, also genug. 😉



  • Ethon schrieb:

    std::size_t kann schlicht für alle Speichergrößen verwendet werden und ist eigentlich immer exakt so groß, um jedes Byte das der Prozessor addressieren kann auch selbst darstellen könnte. Wären unter 64bit immerhin 16.777.216 Terrabyte, also genug. 😉

    Muß nicht sein. Stell Dir DOS vor mit einem Speichermodell, wo kein Objekt größer als 64k sein kann, aber Zeiger 32-bittig sind.
    Desdawegen ist ja auch die Adressvergleicherei in C++ nicht garantiert, wenn man Zeiger aus verschiedenen Objekten vergleicht.

    Aber faktisch kann man davon ausgehen. Da reicht es sogar, wie ich eingangs sagte, gegen 0 zu prüfen (also (sizeof(Element)<<n)==0 mit einer Zweierpotenz als sizeof(Element)).


Anmelden zum Antworten