Fragen zu Heap und Stack
-
Nun, ich erstelle eigenhändig zu Hause eine Klasse, die der Laufzeitbibliothekenklasse <string> ähnelt. Mit ihr soll man leichter mit Strings arbeiten können, da <string> meiner Meinung nach relativ schwierig zu handhaben ist. Hier mal ein paar kleinere Ausschnitte:
(...) #include <iostream> using namespace std; (...) typedef unsigned __int8 BYTE //zur Kompatibilität mit anderen Copilern typedef unsigned __int32 DWORD (...) class CExceptionMemory { void low_memory() { cerr<<"Es steht nicht genug Speicher zur Verfügung. Programm wird beendet...\n"; cin.get(); exit(1); } (...) }; (...) class CString_D { public: CString_D(BYTE *pszInput) {(...)} //Diese Konstruktoren arbeiten CString_D(BYTE cInput) {(...)} //mit C-Strings auf dem Stack, CString_D(char *pszInput) {(...)} //da intern keine delete-Operation CString_D(char cInput) {(...)} //vorgenommen wird. ~CString_D() {(...)} //Destruktor (...) //Hier kommt das Problem: CString_D operator-(DWORD number) { //Erstellt einen Pufferstring BYTE *pTemp; //Zeiger auf Speicher im Heap try { if((pTemp=new BYTE[m_dwLenght-number])==NULL) throw CExceptionMemory(); } catch(CExceptionMemory &exception) { exception.low_memory(); } (...) //Nach der Bearbeitung soll der String zur Konstruktion //eines CString_D-Objekts benutzt werden return CString_D(pTemp) //Hier ist der Fehler } }; (...)In diesem Beispiel wird in dem überladenem Operator - ein Zeiger auf Speicher im Heap eingerichtet. Doch der Speicher wird im Konstruktor nie freigegeben. Wenn ich allerdings eine delete-Operation in die Konstruktoren einbaue, haut mir mein Betriebssystem eine Fehlermeldung aus, sobald ich versuche, einen String als Argument auf dem Stack zu übergeben, da dieser Speicher nicht freigegeben werden kann. Deshalb: gibt es eine Möglichkeit, herauszufinden, ob ein Zeiger auf Speicher im Stack oder im Heap verweisst, am besten in einem if-Vergleich, und dann die jeweilige Aktion ausführen?
-
//Diese Konstruktoren arbeiten //mit C-Strings auf dem Stack, //da intern keine delete-Operation //vorgenommen wird.oO
BYTE *pTemp; //Zeiger auf Speicher im Heap try { if((pTemp=new BYTE[m_dwLenght-number])==NULL) throw CExceptionMemory(); } catch(CExceptionMemory &exception) { exception.low_memory(); } (...) //Nach der Bearbeitung soll der String zur Konstruktion //eines CString_D-Objekts benutzt werden return CString_D(pTemp) //Hier ist der Fehler }Du pruefst auf einen NULL-Zeiger bei new, dann wirfst du eine Exception um sie gleich danach wieder zu fangen und zu bearbeiten. Wie waere es mit einfachen if-Verschachtelung. Desweiteren ist die Namensgebung CExceptionMemory ungeschickt, besser vom Inhalt her trifft es wohl CMemoryException ...
gibt es eine Möglichkeit, herauszufinden, ob ein Zeiger auf Speicher im Stack oder im Heap verweisst
Nein!
da <string> meiner Meinung nach relativ schwierig zu handhaben ist
Echt? Finde ich nicht und ich muss taeglich damit arbeiten. Ausserdem ist es ein schlechter Grund, Standards solltest du persoenlichen Vorlieben vorziehen.
-
Na toll. Trotzdem, danke für die Hilfe. (Werde ich wohl einen eigenständigen Konstruktor kreieren müssen...)
-
Das hat nicht viel Sinn, was du versuchst. Erstens scheinst du dich nicht sehr gut mit manueller Speicherverwaltung auszukennen (beispielsweise wirft
newbei Fehlschlag einestd::bad_alloc, anstatt einen Nullzeiger zurückzugeben). Zweitens sind die Konstrukte aus der Standardbibliothek vorerst immer vorzuziehen, ausser man hat einen guten Grund (zum Beispiel eine spezielle Funktionalität oder wirklich schlimme Performanceprobleme), was aber selten vorkommt.Mich würde bei der Gelegenheit auch mal interessieren, was du an der Handhabung von
std::stringschwierig findest - und welche Vorteile du dir im Gegenzug von deiner eigenen Klasse erhoffst. Viel einfacher alsstd::stringkann man sich meines Erachtens eine Zeichenketten-Verwaltungsklasse nicht mehr vorstellen. Zudem hast du da Fehlerabfragen, Assertions, das Iteratoren- und Algorithmenkonzept, das du selber auch alles implementieren müsstest. So trivial ist das nicht.Kurz gesagt, der Aufwand lohnt sich nicht wirklich...