Memoryleaks ...



  • Aua.

    MFC ist nicht C++, dies ist nur ein Framework. Und ein unlogisch aufgebautes noch dazu - im Zweifelsfalle lässt du die Finger davon.

    In C++/CLI gibt es die Zuweisung:

    ^Objekt=nullptr;
    

    , mit der man den GC anweisen kann, das Objekt zu löschen. In C# geht's noch einfacher:

    Objekt=null;
    

    Aufgrund der vielvältigen Möglichkeiten von C++ kann man Operatoren, Konstruktoren und Destruktoren überladen, sodass delete 'implizit' ausgeführt wird. Bei CString brauchst du dir solange keine Sorgen zu machen, wie du nicht new verwendest, und bei mehreren Strings kannst du die Klasse CStringArray verwenden, lass also die Schnapsidee mit dem Überprüfen.

    CString ist ein Teil der MFC und steht nicht im Gegensatz dazu. Wie das mit der Standardgröße aussieht, weiß ich nicht - ich meine, die Klasse string aus der Laufzeitbibliothek (nicht MFC, es stellt aber kein Problem da, diese einzubinden - einfach:

    #include <string>
    using namespace std;
    

    am Anfang der Datei einfügen, dann ist diese nutzbar) stellt standardmäßig 20 Bytes oder so zur Verfügung, bis diese erweitert werden müssen (kann auch direkt am Anfang sein).

    Ein Prozess kann, wenn er nicht speziell beschränkt wurde, über so viel Speicher verfügen, wie er braucht. Auf 32-Bit-Systemen besteht allerdings für jeden Prozess eine 4-GB-Grenze (bei 64 Bit gibt es auch eine, aber die ist zur Zeit noch vom jeweiligen OS definiert). Du kannst also so viel Speicher, wie du adressieren kannst, vollmüllen.

    Ansonsten: RTFM, und lern die verdammte Sprache. Sowas sollte in jedem Lernbuch erklärt werden, es sei denn, es ist von JW.



  • Sorry .. Da habe ich was verwechselt. Ich meinte nicht Memoryleaks, sondern Heapoverflow durch Defragmentierung. Speziell bei meinem zuletzt genannten Programm. Ihr müsst entschuldigen. Wenn jemand was weiss, unter diesen Voraussetzungen.



  • Mondschein schrieb:

    Sorry .. Da habe ich was verwechselt. Ich meinte nicht Memoryleaks, sondern Heapoverflow durch Defragmentierung. Speziell bei meinem zuletzt genannten Programm. Ihr müsst entschuldigen. Wenn jemand was weiss, unter diesen Voraussetzungen.

    Gibts bei Dir ein Problem diesbezüglich? Ich rate Dir, wenn die Fragmentierung im Moment kein Problem darstellt - kümmere Dich nicht drum! Macht auf mich ein wenig den Eindruck, dass Du Probleme lösen willst die (noch) keine sind!

    [EDIT]
    Und zu deinem letzdem Programm:
    Da werden einige Strings innerhalb der Schleife angelegt (auf dem Stack) und wieder zerstört. Überhaupt kein Problem.



  • Glühbirne schrieb:

    Auf 32-Bit-Systemen besteht allerdings für jeden Prozess eine 4-GB-Grenze

    Unter Windows sind's ohne Tricks nur 2 GB pro Prozess.



  • _matze schrieb:

    Glühbirne schrieb:

    Auf 32-Bit-Systemen besteht allerdings für jeden Prozess eine 4-GB-Grenze

    Unter Windows sind's ohne Tricks nur 2 GB pro Prozess.

    Ja, gut, wenn man die entsprechende Option nicht im Linker setzt oder gleich die Exe neu codiert, sind's wirklich 2 GB. 4 GB sind das Maximum an virtuellen Arbeitsspeicher, was unter 32 Bit geht. Heißt aber noch lange nicht, dass diese auch genutzt werden, denn das Betriebssystem entscheidet über sogenannte Pagefiles, bei welchem Prozess welche virtuelle Speicheradresse mit einer reellen Speicheradresse verknüft wird. Existiert kein Eintrag, gibt's eine Access Violation aka Segfault.

    Wenn du dir Sorgen um die Fragmentierung machst, könntest du auf einen kleinen Trick zugreifen. Du ändert die maximale Größe des Stacks in einen recht hohen Wert und definierst dann ein Bytearray mit vielen Elementen, so viele, wie du brauchst. Das hat den Vorteil, dass du dir erstens sicher sein kannst, dass der Speicher zusammenbleibt, und dass das System schnell ist.

    Allerdings darfst du dich dann selbst um die Speicherverwaltung deiner Strings kümmern, CString wird sich ohne tiefgreifende Änderung wohl kaum davon überzeugen lassen, alle Elemente plötzlich auf den Stack zu legen, zumal der Klasse auch die entsprechenden Informationen fehlen.

    So könnte das Ganze aussehen:

    //Array auf dem Stack, von wo sich deine Klasse den Speicher holt.
    BYTE*MemStack[1073741824]; //1 GB sollte genügen, oder?
    
    //Eigene Stringklasse:
    class MemString{...};
    

    Allerdings kann ich dir sagen, dass dahinter ein Haufen Arbeit steckt. Du musst dir merken, wo das Ende des genutzten Speichers ist, und wo jedes Objekt anfängt und wie lang es ist (es sei denn, die Objekte sollen so lange bestehen wie das Array). Die Werte musst du direkt in den Speicher schreiben und mit Zeigern referenzieren. Alternativ kannst du auch die SmartHeapLibrary nehmen, die sorgt ebenfalls dafür, dass du den Speicher schonst, ist aber wesentlich angenehmer.

    Oder du machst gleich Nägel mit Köpfen und überlädst den new -Operator global, sodass jede Anfrage nach Speicher auf dem Heap (wenn er über new läuft) über deine Überladung läuft. Dann kannst du es dir sparen, eigene Klasse zu entwickeln, die auf Speicher zugreifen.

    Dir bleiben also 3 Möglichkeiten:

    1. Eigene Speicherverwaltung und eigene Klasse.
    2. Externe Bibliothek (SmartHeapLibrary oder andere, ich kenn nur die eine)
    3. Überladung von new , vobei du hier vorsichtig sein musst, nicht bereits in ein bestehendes Speichersystem zu intervenieren.



  • theta schrieb:

    [EDIT]
    Und zu deinem letzdem Programm:
    Da werden einige Strings innerhalb der Schleife angelegt (auf dem Stack) und wieder zerstört. Überhaupt kein Problem.

    stimmt so nicht ganz, CStrings allokieren natuerlich Speicher auf dem Heap sobald ihnen ein String zugewiesen wird.

    Dirk



  • dbu schrieb:

    theta schrieb:

    [EDIT]
    Und zu deinem letzdem Programm:
    Da werden einige Strings innerhalb der Schleife angelegt (auf dem Stack) und wieder zerstört. Überhaupt kein Problem.

    stimmt so nicht ganz, CStrings allokieren natuerlich Speicher auf dem Heap sobald ihnen ein String zugewiesen wird.

    Dirk

    Ja, natürlich. Ausser es kommt gerade die Small String Optimization zum Einsatz (sofern implementiert). Irgendwie denke ich einfach es spielt für den Fragesteller erstmal keine Rolle. Er sollte besser erst die Grundlagen lernen.



  • Jetzt weiss ich immer noch nicht, wie das Heapmanagement arbeitet, speziell bei CString-Objekten. Gibt es Links ? Wenn ja welche ?



  • In einem Buch ( Vermutlich Petzold Visual C++ 6.0 Kapitel: "Dynamische ..." ), habe ich gelesen, dass CString ein Ärgernis darstellt , weil immer wieder kleine Speichereinheiten belegt und freigegeben werden. Und ausserdem dass Microsoft in letzter Zeit einige Verbesserungen diesbezüglich vorgenammen hat. Was wurde wie verbessert ?



  • Willst du mich verarschen?

    CStrings
    C++-Strings im Allgemeinen (steht auch einiges über Speicherverwaltung drin)
    [URL=http://lmgtfy.com/?q=C%2B%2B Heap]Generelles über den Heap[/URL]

    Warum kannst du nicht wie jeder andere auch Google verwenden? Ich hoffe, du schämst dich.



  • Ich suche ja die ganze Zeit bei Google mit den verschiedensten Begriffen. Ohne Erfolg. Ich gebe mich geschlagen, und schäme mich.



  • Das kaufe ich dir nicht ab. Allein schon beim Ausdruck 'C++-Strings' bekomme ich einiges geliefert, was mir vieles über die Speicherverwaltung verrät. Du darfst eben nicht nur die ersten zwei Einträge beachten.

    Nein, jetzt reicht es. Ich habe dir bereits geschrieben, welche Lösungen du verwenden kannst. new überladen, eigene Klassen oder externe Heap-Bibliothek. Du solltest dein Buch wegwerfen und dich mit den grundlegenden Konzepten von C++ und der Speicherverwaltung von heutigen Systemen bekannt machen. Wann du so weit bist? Bis du eine eigene Stringklasse entwickeln kannst, ist gar nicht so schwer, wenn man weiß, wie.

    Hier weitere Referenzen - dabei lernt man so viel über den Speicher und die Schreibe- und Lesealgorithmen, die jede vernünftige Stringklasse verwendet, dass du dich danach nie wieder fragen musst, wie das geht.



  • Mondschein schrieb:

    In einem Buch ( Vermutlich Petzold Visual C++ 6.0 Kapitel: "Dynamische ..." ), habe ich gelesen, dass CString ein Ärgernis darstellt , weil immer wieder kleine Speichereinheiten belegt und freigegeben werden. Und ausserdem dass Microsoft in letzter Zeit einige Verbesserungen diesbezüglich vorgenammen hat. Was wurde wie verbessert ?

    - schau dir den Quellcode an, dann wuerdest du inzwischen wissen, wie und wann CStrings Speicher auf den Heap anfordern und wann dieser wieder freigegeben wird.
    - "smal string optimierungen" gibt es zumindest in der aktuellen Implementierung, die auf den ATL-Strings basiert, nicht. "smal string optimierungen" sind z.Z. (VC++ 2010) nur in std::string zu finden.
    - "heapmanagement" ist uebrigens kein Bestandteil von CStrings sondern von Windows selbst und wurde/wird von MS in jeder Version des OS weiter optimiert. Heapfragemtierung spielt bei modernen Heapmanagern in der Praxis fast nie eine nennenswerte Rolle.

    Dirk


  • Mod

    Mondschein schrieb:

    In einem Buch ( Vermutlich Petzold Visual C++ 6.0 Kapitel: "Dynamische ..." ), habe ich gelesen, dass CString ein Ärgernis darstellt , weil immer wieder kleine Speichereinheiten belegt und freigegeben werden. Und ausserdem dass Microsoft in letzter Zeit einige Verbesserungen diesbezüglich vorgenammen hat. Was wurde wie verbessert ?

    Petzold? C++ und CString. Charles Petzold hat IMHO nie etwas über CString geschrieben.
    Such mal nach "CString Petzold" 😉 Du wirst diesen Thread finden auf Platz 1...

    Es wird soviel unsachlicher Stuss verbreitet, dass man auch diese Äußerung in diese Kategorie einordnen dürfen. Werde konkret mit Beispieln, Zitaten und Quellen...



  • Glühbirne schrieb:

    _matze schrieb:

    Glühbirne schrieb:

    Auf 32-Bit-Systemen besteht allerdings für jeden Prozess eine 4-GB-Grenze

    Unter Windows sind's ohne Tricks nur 2 GB pro Prozess.

    Ja, gut, wenn man die entsprechende Option nicht im Linker setzt oder gleich die Exe neu codiert, sind's wirklich 2 GB. 4 GB sind das Maximum an virtuellen Arbeitsspeicher, was unter 32 Bit geht.

    4 GB sind das theoretische Maximum, unter 32-Bit-Windows aber nicht möglich (da gehen maximal 3 GB). Erst unter x64 mit LAA-Flag kann ein 32-Bit-Prozess volle 4 GB verbraten. (Siehe http://msdn.microsoft.com/de-de/library/bb978906.aspx)


Anmelden zum Antworten