Ergebnis 1 bis 1 von 1

Thema: [C++] Hab ich da irgendwo einen Fehler reingebaut? ^^

  1. #1

    [C++] Hab ich da irgendwo einen Fehler reingebaut? ^^

    Hallöchen,

    das C++ Forum ist offline, ihr seit meine letzte Rettung.
    Ich benötige eine Bestätigung, dass ich nicht den totalen Mist verbrochen habe. Es geht um folgendes:

    Ich habe mehrere Funktionen bei denen ich einen Speicherbereich zurückgebe, die Größe dabei ist variabel. Etwa so:

    Code:
    Pseudocode: (syntaktisch falsch)
    char* Funktion()
    {
    char* buffer = new char* [20]
    buffer = "Bla bla bla"
    return buffer
    }
    Mir ist dabei klar, dass der Speicher nicht freigegeben wird und somit verfault. Das soll nicht sein, daher habe ich mir eine Methode überlegt, mit der ich der Funktion ein Objekt übergebe welches einen pointer enthält. Dann kann die Funktion den Pointer manipulieren wie sie will und Dinge hinein schreiben. Wenn das Objekt dann aus dem Scope fällt und der destruktor aufgerufen wird, wird der allokierte Speicher freigegeben. Das Objekt soll aber nicht innerhalb der Funktion erzeugt werden da der Speicher dann bei dem Rückgabewert der Funktion schon freigegeben werden würde. Das Objekt mit dem Pointer wird also im Hauptcode erstellt, von dem aus dann die Funktion aufgerufen wird.

    Das sieht dann so aus:
    Code:
    Pseudocode: (syntaktisch falsch)
    char* Funktion( object_klasse &name)
    {
    name = new char* [20]
    name = "Bla bla bla"
    return name
    }
    
    Hauptcode:
    {
    object_klasse xyz   //objekt mit pointer erstellen
    cout<<Funktion( xyz )<<endl
    } //hier wird der Speicher im Pointer mittels Destruktor des Objekts freigegeben
    Ich hoffe es ist klar wie ich das meine. Der Pointer wird praktisch vor der Funktion außerhalb im Hauptcode erzeugt (in einem Objekt) und dann übergeben an die Funktion. Die Funktion schreibt ihre Werte rein und gibts zurück. (Dabei wird das Objekt direkt als Referenz benutzt und KEINE Kopie des Objekts).


    Als richtiger Code nun sieht das so aus:

    Code:
    #include <iostream>
    
    using namespace std;
    
    
    class pointer_class
    {
    private:    int size;
    public:     char* pointer;
                bool change_size(int new_size, bool flag = false);      //Used to reallocate new memory //true = save old content //false = clear all
                bool write( char*, int = -1);
                pointer_class( int );
                ~pointer_class( void );
    };
    
    bool pointer_class::write( char* new_content, int length)
    {
        if (length == -1)
        {
            length = strlen( new_content );
        }
        if (length <= size)     //only if pointer is holding enough memory
        {
            memcpy(pointer, new_content, length);
            return true;
        }
        return false;
    }
    
    bool pointer_class::change_size(int new_size, bool flag)
    {
        //flag true = keep content
        //flag false = clear content
    
        if (flag == true)       //keep content
        {
            if (size > 0)
            {
                char* old_content = new char [size];        //allocate memory for old content to keep it
                memcpy(old_content, pointer, size);         //save old content
                delete [] pointer;                          //delete pointer for reallocating soon with new size
                pointer = new char [new_size];              //allocate new memory
                memset(pointer, 0, new_size);               //set all to zero
                memcpy(pointer, old_content, new_size);     //fill in old memory till end of new buffer or till everything is in
                delete [] old_content;                      //delete temporary buffer for old content;
                size = new_size;                            //set new size
                return true;
            }
    
            pointer = new char [new_size];
            memset(pointer, 0, new_size);
            size = new_size;
            return true;
        }
        else        //clear content
        {
            if (size > 0)
            {
                delete [] pointer;
            }
            pointer = new char [new_size];
            memset(pointer, 0, new_size);
            size = new_size;
            return true;
        }
        return false;
    }
    
    pointer_class::pointer_class( int p_size)
    {
        if (p_size != -1)
        {
            pointer = new char [size];
            memset(pointer, 0, size);
            size = p_size;
        }
        else
        {
            pointer = NULL;
            size = 0;
        }
    }
    
    pointer_class::~pointer_class( void )
    {
        if (size > 0)
        {
            delete [] pointer;
        }
    }
    
    char* testfunction( pointer_class &ext_buffer)
    {
        ext_buffer.change_size(4096);       //change size of buffer and zero everything
        memcpy(ext_buffer.pointer, "DIES IST DER NEUE INHALT DES SPEICHERBEREICHS", strlen("DIES IST DER NEUE INHALT DES SPEICHERBEREICHS"));        //set zero for testing
    
        return ext_buffer.pointer;
    }
    
    
    
    int main()
    {
        pointer_class buffer(-1);
        cout<<testfunction(buffer)<<endl;
        cin.get();
    
        return 0;
    }
    Mir ist bewusst, ich begehe da schwere OOP-Fehler da der Pointer im Public bereich ist und somit frei manipuliert werden kann. Doch anders lässt es sich manchmal nicht machen (da manche WinAPI-Funktionen den reichen Pointer als Parameter benötigen und wenn der geschützt ist die Funktion einen Zugriffsfehler rausgibt). Daher brauche ich manchmal den ungeschützten reinen pointer aus dem Objekt welcher deshalb public ist.

    Das Ganze wird eine recht komplexe Änderung in meinem Programm werden daher würde ich gern vorher wissen, ob der Code so korrekt ist. Es gibt bei mir keine Fehlermeldungen.
    Wichtig ist, dass keinerlei Dinge im Speicher vergessen werden und keine Zugriffsfehler oder Ähnliches auftreten.
    Wär' also nett wenn sich ein Kundiger mal den Code ansehen könnte und schaut ob alles ok soweit ist. Wie gesagt, das wären recht große Einschnitte wenn ich den Code einbaue, dann sollte er auch gehen. Nicht, dass später bei längerer Benutzung Speicherlöcher auftreten die dann schwere Fehler verursachen.

    mfg

    Ynnus

    Geändert von Ynnus (03.10.2005 um 21:19 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •