size_t und das Dateisystem



  • Erhard Henkes schrieb:

    2^64 = 18.446.744.073.709.551.616
    2^32 = 4.294.967.296

    Bei MS VS 2015 in vcruntime.h:

    // Definitions of common types
    #ifdef _WIN64
        typedef unsigned __int64 size_t;
        typedef __int64          ptrdiff_t;
        typedef __int64          intptr_t;
    #else
        typedef unsigned int     size_t;
        typedef int              ptrdiff_t;
        typedef int              intptr_t;
    #endif
    

    Also gibt es da einen Unterschied bei 32 und 64bit Systemen?



  • Bennisen schrieb:

    Also gibt es da einen Unterschied bei 32 und 64bit Systemen?

    Yup.

    Und noch was: genau deswegen solltest du immer size_t oder uintptr_t bei Größen verwenden. Auf keinen Fall unsigned int oder dergleichen. size_t garantiert dir, dass es groß genug ist, um Längen zu halten - dass es auf 64-Bit-Systemen ohne Segmentierung 8 Byte groß ist. Auf Windows ist ein unsigned int aber 32 Bit. Deswegen merke: immer size_t/uintptr_t verwenden, und keine eigenen Typen erfinden. 😉



  • dachschaden schrieb:

    Bennisen schrieb:

    Also gibt es da einen Unterschied bei 32 und 64bit Systemen?

    Yup.

    Und noch was: genau deswegen solltest du immer size_t oder uintptr_t bei Größen verwenden. Auf keinen Fall unsigned int oder dergleichen. size_t garantiert dir, dass es groß genug ist, um Längen zu halten - dass es auf 64-Bit-Systemen ohne Segmentierung 8 Byte groß ist. Auf Windows ist ein unsigned int aber 32 Bit. Deswegen merke: immer size_t/uintptr_t verwenden, und keine eigenen Typen erfinden. 😉

    Ok danke für den Tipp.

    Aber was wäre denn wenn ich, bei 32bit, die Größen von 4 Dateien, die jeweils 5 GByte groß sind, als gesamte Größe in size_t speichern möchte?



  • #include <iostream>
    #include <cstdint>
    
    int main()
    {
    	uint8_t a = 42 ;
    	uint16_t b = 42;
    	uint32_t c = 42;
    	uint64_t d = 42;
    	size_t e = 42;
    	int f = 42;
    
    	std::cout << sizeof(a) << " " << sizeof(b) << " " << sizeof(c) << " " << sizeof(d) << " " << sizeof(e) << " " << sizeof(f) << std::endl;
    }
    

    x86: 1 2 4 8 4 4
    x64: 1 2 4 8 8 4

    Hier sieht man den Vorteil von size_t bei einer Migration von 32 nach 64 bit bei der Kompilierung. Die normalen Typen bleiben allerdings gleich, übrigens auch int. Beides hat seine Vor-/Nachteile.



  • Bennisen schrieb:

    Ok danke für den Tipp.

    Aber was wäre denn wenn ich, bei 32bit, die Größen von 4 Dateien, die jeweils 5 GByte groß sind, als gesamte Größe in size_t speichern möchte?

    Windows hat dafür einen speziellen API-Call, GetFileSizeEx. Die Funktion übernimmt einen Zeiger auf einen LARGE_INTEGER, der 64 Bit groß ist.

    Unter POSIX-Systemen wird off_t verwendet. Allerdings nicht direkt - meist wird direkt stat genommen. Gibt's auch unter Windows als _stat , aber meines Wissens ist das nicht mehr direkte, nakte API.

    Und der Hirnriss bei beiden Typen ist, dass die signed sind ... und 64 Bit. Aber dennoch signed.

    EDIT: Übrigens: wenn du versuchst, einem 32-Bit-Speicherbereich mehr zuzuweisen, als er halten kann, wird der Bereich, den er nicht halten kann, abgeschnitten. Und das ist der Vater aller Sicherheitslücken - ich will 0x1 0000 0001 Elemente haben, der dumme Programmierer speichert das aber in einem 32 Bit-Wert, der große Teil wird abgeschnitten, malloc/new bekommt nur was von einem Element mit, und dann kann ich schön in den Heap schreiben.



  • also könnt ihr mir empfehlen off_t zu verwenden, wenn ich die Größe von Dateien erfassen oder zusammenfassen möchte?
    Hab es gerade mal im Code eingebaut. Funktioniert momentan ohne Probleme.



  • Ich würde eher streamoff empfehlen. Das ist immerhin im Standard und dürfte über Überwege dem Typ entsprechen den tellg/tellp/seekg/seekp nutzen. Oder wenn du den Typ gar nicht selbst genau wissen musst einfach auto benutzen.



  • Wenn es Dir nicht um besondere Funktionalitäten geht, sondern lediglich um die Dateigröße in Byte, dann kannst Du einfach uint64_t verwenden. Damit kannst Du bis 2^64 - 1 Byte speichern. Größere Filegrößen könntest Du als KB oder MB abspeichern, oder wenn es ganz exakt in Byte sein muss, dann mit BigInteger-Klassen. ich verwende für so etwas z.B. eine reduzierte BigUnsigned-Klasse: http://henkessoft.de/Sonstiges/MyBigUnsigned.rar



  • Vielen Dank ich werde mir das mal alles anschauen.

    Noch eine Offtopic Frage...

    Ich bin jetzt ein normaler User und hatte bisher Server mit Dateien die nicht größer als ca. 1GByte waren. Gibt es in größeren Infrastrukturen auch Dateien die "um einiges" größer werden als ein paar GByte?



  • Erhard Henkes schrieb:

    Damit kannst Du bis 2^64 - 1 Byte speichern. Größere Filegrößen [...]

    Naja mit 64 Bit kann man schon Dateigrößen darstellen die bis 18 Mio. TB gehen. Bis wir dort sind wird es wohl noch ein Weilchen dauern. Und damit kommen wir auch schon zur OT Frage. Wie definierst du "um einiges"? Ich habe schon 50GB Dateien mit meinen C++ Programmen produziert und weiter verarbeitet. Und das ist ja auch noch nichtmal groß. Festplatten mit 1TB und mehr gibts an jeder Straßenecke. Mit größeren Speichersystemen kriegt man auch einige 100 TB Speicherplatz aber mich wurde schon wundern wenn dort wirklich nur eine große Datei drauf liegt. Prinzipiell arbeitet man mit diesen Dateien aber auch nicht anders als mit kleineren Dateien. Gut man kann sich schonmal nicht alles in den RAM kopieren, höchstens Ausschnitte.



  • da ich eh boost verwende, habe ich jetzt uintmax_t dafür benutzt. Problem gelöst. Danke nochmal.


Anmelden zum Antworten