Gibt es eine ofstream Grenze?



  • Hallo.

    ich habe eine Algorithmus geschrieben der mir mit der STL Funktion next_permutation() Permutationen (123 -> 231, 132...) berechnet. Danach schreibe ich die Ergebnisse in eine Datei.

    ofstream fout("data.dat");  
    
             for (int i=0; i< (int)vStr.size(); i++) 
             {
                if (i) 
                  fout <<", ";
                fout << vStr[i];
             }
             fout << endl;
             fout.close();
    

    Ab einer Stringgröße von 11, also bei Eingabe von "abcdefghijk" wird das Programm nach ein paar Minuten extremen Festplattenzugriff mit einem Laufzeitfehler beendet. Meine Frage: Gibt es eine Grenze bei Verwendung von ofstream() oder muss ich die Ergebnisse eventuell anders speichern?



  • Ich nehm jetzt einfach mal an, die Probleme erscheinen ab einer Länge von 12 Zeichen. Wenn du eine FAT32-Partition hast, dann können deine Dateien nur 2oder 4 GB groß sein.

    Es gibt 12! = 479.001.600 Permutationen
    Jedes mal schreibst du 14 Zeichen, also
    12! * 14 Zeichen = 6.706.022.400 Zeichen = 6.705.022.400 Byte = 6,25 GB



  • Michael E. schrieb:

    Ich nehm jetzt einfach mal an, die Probleme erscheinen ab einer Länge von 12 Zeichen. Wenn du eine FAT32-Partition hast, dann können deine Dateien nur 2oder 4 GB groß sein.

    Es gibt 12! = 479.001.600 Permutationen
    Jedes mal schreibst du 14 Zeichen, also
    12! * 14 Zeichen = 6.706.022.400 Zeichen = 6.705.022.400 Byte = 6,25 GB

    Erst einmal danke für die Antwort! 🙂

    Ich habe zuätzlich 2 Byte Zeichen im Code die die Zahlen trennen mit Leerzeichen und Bindestrich. Ich habe nun ausgerechnet das bei 11 Zeichen also 11! -> 39916800 * 13 = 518918400 / 1024 / 1024 = 494,879 MB anfallen. Die Rechnung stimmt mit den erhaltenen Dateigrößen für kleinere Strings überein. Ich teste das ganze auf einer NTFS Partition. Ab exakt 11 Zeichen wird das Programm wie oben beschrieben, nach minutenlanger Festplattenaktivität beendet. An der maximalen Dateigröße auf Fat32 Partitionen kann es also nicht liegen. 😞

    Grüße



  • Ich vermute, dein Programm kommt gar nicht dazu, irgendwas auf die Platte zu schreiben, weil dir schon vorher der Speicher ausgeht. Es wäre besser, wenn du nicht zuerst alle Permutationen ermittelst, und dann alles auf einmal auf die Platte schreibst. Welchen Container benutzt du denn da überhaupt?



  • Solange du kein "cout << flush" aufrufst, wird alles im Speicher gehalten.



  • Th schrieb:

    Solange du kein "cout << flush" aufrufst, wird alles im Speicher gehalten.

    falsch, die implementation entscheided, wann geschrieben wird. ist der buffer voll gibts keinen größeren, sondern es wird in die datei geschrieben. Natürlich kann man das schreiben mit flush erzwingen, aber das muss man nicht.



  • Auch bei NTFS wirst Du entweder an der 2 oder 4 GB Grenze scheitern - weil die Standardbibliothek das einfach nicht kann. Du brauchst hier spezielle OS-Funktionen. Da Du unter Windows bist, ist die einzig offizielle Möglichkeit für 64-Bit Dateizugriff CreateFileMapping. (CreateFile geht meines Wissens nach auch, wird aber in der API-Doku net ausdrücklich als dafür geeignet erwähnt)

    Aber an Dateigrößen scheint es erstmal noch nicht zu scheitern. Kann es nicht einfach sein, dass Dir Speicher & Swapspace ausgeht? Deshalb auch das Plattenrödeln. Beobachte das doch mal im Taskmanager.



  • MFK schrieb:

    Ich vermute, dein Programm kommt gar nicht dazu, irgendwas auf die Platte zu schreiben, weil dir schon vorher der Speicher ausgeht.

    Möglich. Die Belastung der CPU (2,6GHz) steigt zu Beginn auf 100% an und sinkt nacht wenigen Sekunden auf 3% ab. Der Arbeitsspeicher (512MB) wird vollständig aufgebraucht und die Auslagerungsdatei steigt sprunghaft an. Die Festplattenaktivität geht ans Maximum und verbleibt dort, bis nach einigen Minuten das Programm beendet wird (Runtime problem...). Ich werde das ganze mal mit 1GB Ram testen.

    MFK schrieb:

    Es wäre besser, wenn du nicht zuerst alle Permutationen ermittelst, und dann alles auf einmal auf die Platte schreibst.

    Daran habe ich auch schon gedacht. Wollte aber vorher mal die Meinung von euch dazu hören. 🙂

    MFK schrieb:

    Welchen Container benutzt du denn da überhaupt?

    vector<string>

    cu



  • vector<string>

    nicht gut wenn man viel hinten einfügen muss.



  • das problem ist aber auch, dass windows dir nie mehr als 4gb arbeitsspeicher zur verfügung stellen wird.



  • otze schrieb:

    das problem ist aber auch, dass windows dir nie mehr als 4gb arbeitsspeicher zur verfügung stellen wird.

    2 oder 3



  • Snack_Hippo schrieb:

    Ich werde das ganze mal mit 1GB Ram testen.
    ...
    vector<string>

    Überschlag das doch einfach mal: Du brauchst 11! = 39916800 Strings.
    Jeder String hat 11 Zeichen, dazu kommt die Instanz der String-Klasse selbst. sizeof(std::string) ist bei mir (VS.NET2005B2) 28. Das macht dann schon mal mindestens 1,45 GByte.

    Wenn du nicht von Anfang an den vector auf die richtige Länge setzt, muss der irgendwann seinen Inhalt umkopieren, um sich zu vergrößern. Das kann den Speicherbedarf mal eben verdoppeln.

    Ich empfehle dir, die ermittelten Permutationen gleich in die Datei zu schreiben.



  • Wieso nimmst du nicht einfach mehere Dateien? Also so etwa bei 512MB öffnest du einfach eine neue Datei und schreibst darin.



  • sag mal was bringt das eigentlich wenn der müll in der datei steht??


Anmelden zum Antworten