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 new bei Fehlschlag eine std::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::string schwierig findest - und welche Vorteile du dir im Gegenzug von deiner eigenen Klasse erhoffst. Viel einfacher als std::string kann 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...


Anmelden zum Antworten