Speicherverwaltung
-
matti83 schrieb:
* Du versuchst mit dem Ansatz, benutzerfreundlich zu sein, und den Speicher automatisch freizugeben, wenn er vom Benutzer dynamisch angefordert wurde. Die Idee ist prinzipiell sehr gut, aber das mit der Benutzerfreundlichkeit geht komplett nach hinten los.
Den Punkt kann ich abhaken, weil der Benutzer genau weiss was er macht, wenn er meinen GC nutzt
Dann kann ich nur hoffen, das der Benutzer ausschließlich mit deinen GC arbeiten muss, damit er nicht ständig durcheinander geraten kann. Ein GC widerspricht der C++ Programmierung weitgehend (Thema RAII).
Wobei durchaus (für ein speziellen TR ausgelagert) eine Überlegung gibt einen optionalen C++ GC einzuführen, den man aber entweder nur ganz oder garnicht aktivieren kann (War ursprünglich für den kommenden Standard in Diskussion).
matti83 schrieb:
Und da der Benutzer keinen Speicher anfordet, sondern mein GC ist alles gut.
Aber nur wenn sichergestellt ist, das der Speicher AUSSCHLIESSLICH von dir verwaltet wird. Was man wohl ausschließen muss, wenn man nicht jegliche externe Bibliothek ausschließen will.
-
matti83 schrieb:
* Der Grund ist, dass du Konzepte aus anderen Sprachen (Garbage Collector) 1:1 nach C++ übertragen willst, wo Speicherverwaltung aber ganz anders abläuft. C++ hat viel strengere und eindeutigere Besitzverhältnisse als Sprachen mit GC (Speicher ist nicht geteilt, sondern hat meist einen klaren Besitzer). Normalerweise wird der Speicher von dem freigegeben, der ihn anfordert. Mit deinem Versuch verstösst du gegen diese Konvention.
Den Speicher den ich freigebe, kann man auch nur aus meinem GC anfordern. Also hat den auch kein anderer freizugeben. Das mit dem Sprachübergreifend lassen wir mal. In C++ kann man auch nur Speicher anlegen und wieder freigeben. Und da der Benutzer keinen Speicher anfordet, sondern mein GC ist alles gut.
Wenn du nur selber den Speicher anforderst ist es ja easy. Dann weisst du ja welchen Speicher du angefordert hast und weisst somit ob du ihn löschen kannst oder nicht.
Insofern ist es ja keine Frage von stack vs heap - weil du ja eh selber allokierst. Einfach merken was du gemacht hast (das musst du ja sowieso wenn der GC etwas taugen soll). Damit kannst du ganz einfach selber testen ob die allokierung dynamisch stattgefunden hat oder nicht.
Prinzipiell ist so ein GC natürlich blödsinn, aber davon werden wir dich nicht abbringen können fürchte ich.
-
matti83 schrieb:
Also meine alte Frage ob ich diese Unterscheidung zwischen Stack und Heap heraus bekommen kann. Ich wüsste auch nicht warum das nicht gehen sollte.
Was für Auswertungen sollen das sein?
Du könntest den new-Operator überschreiben und dann daran erkennen, wenn ein Objekt mit new angelegt wird...
-
Powerpaule schrieb:
matti83 schrieb:
Also meine alte Frage ob ich diese Unterscheidung zwischen Stack und Heap heraus bekommen kann. Ich wüsste auch nicht warum das nicht gehen sollte.
Was für Auswertungen sollen das sein?
Du könntest den new-Operator überschreiben und dann daran erkennen, wenn ein Objekt mit new angelegt wird...Genau das hab ich jetzt auch vor. Problem ist noch: Welcher Konstruktor oder Operator wird aufgerufen, wenn ich kein NEW benutze? Oder ist dann sichergestellt, dass der Speicher mit 0 initialisiert ist?
Also Membervariable: char stack;
Ohne NEW => stack = 0;
Mit NEW => stack = 1; weil ich den new operator überschreibe und stack auf 1 setzeoder ist bei Ohne NEW der Speicherinhalt undefiniert?
-
dh also dein GC allokiert den Speicher doch nicht. Damit wird es nur sinnloser (falls das moeglich ist). Du kannst nur operator new/delete ueberladen um Speicher zu allokieren, nicht um die Objekte zu erstellen. (operator new/delete zu ueberladen bringt dir also nichts, da du damit nicht die objekte erstellst sondern nur rohen speicher beschaffst).
Sprich du musst dir merken welche adressen du allokiert hast. Dann kannst du spaeter herausfinden ob die adresse allokiert wurde (und somit du den Speicher verwaltest) oder ob das Objekt auf eine andere Art erstellt wurde (bedenke: es muss nicht zwangslaeufig auf den stack erstellt worden sein nur weil kein new aufgerufen wurde).
Was du willst ist keine gute Idee. Es wird nicht vernuenftig funktionieren. Lass uns lieber ueber alternativen nachdenken.
Wenn du einen GC haben willst, dann gibt es naemlich Ansaetze wie man welche verwenden kann die funktionieren. Das Problem ist nur, dass dein Ansatz falsch ist.
-
Sorry .. also ihr interpretiert mir da viel zu sehr, als meine Frage zu beantworten
ich will nur wissen ob es aufm Stack ist oder nicht.
char istAufStack( void* p ) { char onStack; void* sp = (void*)&onStack; return ( p < sp ? 1 : 0 ); } class Pointer { private: char stack; public: Pointer() { stack = ::istAufStack( (void*)this ); } };
-
matti83 schrieb:
ich will nur wissen ob es aufm Stack ist oder nicht.
Geht nicht. Braucht man aber auch nicht.
Es ist vorallem deshalb nicht moeglich, weil der Speicher ja aus einem anderen Thread kommen koennte - von dem weisst du ja nicht wie das Speicherlayout aussieht. Was man zB sehr wohl machen kann, ist herausfinden ob diese adresse auf dem aktuellen thread stack liegt - nur bringt das eben wenig info (da der Speicher ja auch von irgendwo anders kommen kann).
Da es aber vollkommen uninteressant ist wo der Speicher liegt, gibt es unterschiedliche Moeglichkeiten und Wege zu dem Ziel zu kommen dass du hast. Deshalb sollten wir darueber reden was du damit erreichen willst.
Als Beispiel:
Jemand will erreichen dass alle Objekte die per new angelegt werden auch wieder geloescht werden wenn die memberfunktion release() aufgerufen wird.Dann wuerde man entweder erzwingen dass diese Objekte nur ueber eine bestimmte Funktion generiert werden koennen (named constructor idiom). Dadurch ist es einfach zu garantieren dass das Objekt immer auf Variante A erstellt wurde. release() weiss daher wie es sich selbst loeschen kann.
Es gibt hier wahnsinnig viele Moeglichkeiten die unterschiedlichsten Sachen zu erreichen...
-
Ich will alle Objekte die auf einem ThreadStack liegen ROT markieren
-
Shade Of Mine schrieb:
Es ist vorallem deshalb nicht moeglich, weil der Speicher ja aus einem anderen Thread kommen koennte - von dem weisst du ja nicht wie das Speicherlayout aussieht. Was man zB sehr wohl machen kann, ist herausfinden ob diese adresse auf dem aktuellen thread stack liegt - nur bringt das eben wenig info (da der Speicher ja auch von irgendwo anders kommen kann).
in dem Moment, indem das Objekt erstellt wird, kann es doch nur in einem Thread sein... und genau der Thread prüft, ob es auf dessen Stack liegt!?
Also kann der Speicher doch nicht von irgendwo anders kommen...
-
matti83 schrieb:
Ich will alle Objekte die auf dem Stack liegen ROT markieren
Stack Objekte einfach verbieten, dann liegt alles am free store. Fertig. Kein Objekt muss rot markiert werden.
Willst du Hilfe haben oder nicht?
-
matti83 schrieb:
in dem Moment, indem das Objekt erstellt wird, kann es doch nur in einem Thread sein... und genau der Thread prüft, ob es auf dessen Stack liegt!?
Also kann der Speicher doch nicht von irgendwo anders kommen...
Doch, der Speicher kann von ueberall herkommen.
Stell dir mal folgendes vor:
template<typename T> T* create(void* memory) { return new(memory)T(); }
Das objekt wird erstellt, aber der Speicher kann von ueberall herkommen.
-
Shade Of Mine schrieb:
matti83 schrieb:
Ich will alle Objekte die auf dem Stack liegen ROT markieren
Stack Objekte einfach verbieten, dann liegt alles am free store. Fertig. Kein Objekt muss rot markiert werden.
Willst du Hilfe haben oder nicht?
Klar will ich Hilfe haben. Sonst wäre ich nicht hier.
Ich benötige aber StackObjekte, eben weil ich sie ROT markieren möchte... das sind die Objekte, von denen ich alle anderen Objekte ansprechen will... aber es soll eben auch HeapObjekte geben können.
Ich seh schon... du willst mir sagen, das ich zwei unterschiedliche PointerKlassen brauche. Pointer die nur auf dem Stack liegen und Pointer die nur im Heap sind. Aber wenn ich genau drüber nachdenke... wie soll ich das gewährleisten?
-
Meine Güte, man kann echt stur sein. Wenn du tatsächlich Hilfe willst, geh bitte auf die Antworten ein. Jeder hat bis jetzt gesagt, dass die Unterscheidung Stack/Heap im Allgemeinen unsinnig ist. Das wurde inzwischen x-mal erwähnt. Im verlinkten Thread stehts auch noch in jedem zweiten Post. Aber du weisst es natürlich besser.
Wenn du wenigstens eine brauchbare Begründung hättest, könnte man ja noch darüber reden. Aber du willst Objekte "ROT markieren". Schlimm sowas...
-
Verstehe ich nicht... jetzt geht es nicht. Aber wenn ich eine Begründung hätte, warum ich es machen will, dann geht es?
Sehr komisch....
Will hier doch auch niemanden angreifen oder beleidigen. Ich will nur zwischen Stack und Heap Objekten unterscheiden... aber anscheinend geht das nicht.
Meine Begründung hab ich doch geschrieben... und das Argument, dass etwas nicht sinnvoll ist zieht bei mir nicht.
Wenn ich endlich eine Lösung gefunden habe, werde ich sie hier posten. Es sei denn ihr kommt mir zu vor
-
matti83 schrieb:
Verstehe ich nicht... jetzt geht es nicht. Aber wenn ich eine Begründung hätte, warum ich es machen will, dann geht es?
Nein. Es geht nicht.
Aber es gibt viele Lösungen für viele Probleme. Die Problemstellung "Objekte Rot markieren" gibt es nicht, da man Objekte nicht rot markieren kann.
Man kann zB memory Statistiken erstellen, man kann Objekte auf den Stack oder auf den Free Store zwingen. Je nachdem was die Aufgabenstellung ist, gibt es viele Lösungen.
Bedenke: nur weil das Objekt zB auf dem Stack liegt, muss es ja noch lange nicht auch automatisch zerstört werden. Die Unterscheidung Stack/Free Store zu machen ist deshalb nicht möglich und nicht sinnvoll. Auch wenn nicht sinnvoll bei dir nicht zieht - bedenke dass wir immer auch "nicht möglich" dazu sagen. Das nicht sinnvoll sagen wir deshalb dazu, weil es mit sehr großer Wahrscheinlichkeit eine Lösung für dein Problem gibt. Nur dazu musst du uns verraten was du tun willst.
Du willst nicht nur objekte Rot markieren. Du willst damit ja etwas erreichen. Und die Frage ist was das ist. Du hast anfangs geschrieben einen GC zu machen: da gibt es viele Ansätze wie man einen funktionierenden GC machen kann.
Deshalb ist es für uns wichtig zu wissen WAS du machen willst, nicht WIE. Denn dein WIE klappt nicht. Aber das heisst eben auch noch lange nicht dass dein WAS nicht klappt.
Die Unterscheidung Stack/Free Store klappt zB auch deshalb nicht, weil es nicht klar ist was Stack und was Free Store ist wenn du mit mehreren Prozessen hantierst. Denn fremder Speicher ist fremder Speicher. Egal WO er liegt. Thread internen Stack ist ja herausfindbar (auch wenn es dann noch lange nicht bedeutet dass das Objekt automatisch zerstört wird nur weil es auf dem Stack liegt).
-
okay - geht also nicht. schade.
dann muss ich also zwei klassen bauen - eine darf nur auf dem heap erstellt werden und die andere darf nur auf dem stack erstellt werden. und der benutzer muss sich darum kümmern.
dann geh ich davon aus, dass alle StackKlassen auch auf dem Stack sind.