Speicherzuweisung



  • Hallo zusammen,

    ich arbeite gerade ein paar Beispiele zum Thema Speicherzuweisung durch und habe da noch nicht so ganz den Durchblick... (generell in C++ auch noch nicht)

    #include <iostream>
    #include <new.h>
    
    using namespace std;
    
    int main() // Warum geht nicht: void main() ?
    {
        void desborde(); // Anmeldung der Funktion
        int speicher_befreien(); // Anmeldung der Funktion, in der ich den Speicher wieder frei machen will
        set_new_handler (desborde); //das kümmert sich um die Fehlermeldung wenn der Speicher nicht mehr ausreicht
        long groesse;
        int *dir;
        int nbloque;
        cout << "gewünschte Größe: ";
        cin >> groesse;
        for (nbloque = 1; ; nbloque++)
        {
            dir = new int[groesse];
            cout << "Zuweisung Block-Nummer: " << nbloque <<
            endl;
        }
    speicher_befreien(dir);
    return 1;
    }
    
    void desborde()
    {
        cout << "Speicher nicht ausreichend" << endl;
        exit(1);
    }
    
    int speicher_befreien(dir) // hier möchte ich den Speicher wieder frei machen am Ende des Programmes
    {
        delete [] dir;
        return 1;
    }
    

    Die Funktion "speicher_befreien" stand nicht im Beispiel, war meine Idee... klappt auch nicht 😃

    Kann mir da jemand helfen? (Warum klappt eigentlich am Anfang void main() nicht, steht so im Beispiel...)



  • Barcelona schrieb:

    (Warum klappt eigentlich am Anfang void main() nicht, steht so im Beispiel...)

    Weil es falsch ist. Dein Beispiel ist schlecht.



  • Hallo Barcelona,
    gleich mal vorweg besorg dir mal ein anderes Tutorial, dieses ist wie mir scheint nicht gerade gelungen.
    zu erst einmal zu deiner main(), dies ist wie der Name schon sagt die Hauptfunktion in der alle anderen aufgerufen werden können. Diese sollte oder muss vom Typ int sein da sie nach abarbeiten aller Funktionen und Prozeduren einen Fehlerwert zurück geben sollte, der anzeigt, ob alles glatt gegangen ist oder nicht, der ist standartmäßig glaub return 0.
    Zu dem Prog'stil, das Anmelden so wie es dort beschrieben ist nennt sich Prototypen-Deklaration, dies geschieht immer ganz oben in der .cpp-Datei bzw. in einer externen .h-Datei.
    [cpp]
    #include <iostream>
    #include <new.h>

    using namespace std;

    // deklaration
    void desborde();
    int speicher_befreien( *int dir );

    main( ) {

    return 0;
    }

    // definition
    void desborde()
    {
    cout << "Speicher nicht ausreichend" << endl;
    exit(1);
    }

    int speicher_befreien(**int ***dir) // hier möchte ich den Speicher wieder frei machen am Ende des Programmes
    {
    delete [] dir;
    return 1;
    }
    [/cpp]

    die definition, also der Teil wo man den Rumpf der Funktion beschreibt, wird wie hier schon richtig gehandlet nach der main() Funktion vorgenommen, allerdings ist das jedem selbst überlassen wie er es macht, wichtig ist das dem Programm der Prototyp vor Aufruf, bekannt gemacht wurde( "angemeldet" ).

    Das vllt. ersteimal zum wesentlichen. Nun der Teil warum deine Funktion nicht Funktioniert. Du hast vor dem Aufruf von speicher_befreien(dir) den Prototyp wie folgt deklariert speicher_befreien( ), also ohne Parameter, rufst sie aber mit einem Parameter auf. Was du ier also ändern solltest ist die deklaration des Prototyps in speicher_befreien( int *dir ) und vergiss die Variablentypisierung nicht.

    Meine Empfehlung an dich, befass dich lieber erst einmal mit den Grundlegenden Dingen von C++, wie Syntax, Variablentypen und Größen bzw. Speicherbereiche von Variablen.

    Lg Tobi



  • Danke Tobi. Stimmt wohl, dass mir noch ein paar grundlegende Dinge in C++ fehlen, hab' bisher alles in Ruby gemacht... aber diese Basissachen lerne ich dann auch bei Beispielen wie diesem 🙂

    #include <iostream>
    #include <new.h>
    
    using namespace std;
    
    int main() // Warum geht nicht: void main() ?
    {
        void desborde(); // Anmeldung der Funktion
        int speicher_befreien(int *dir); // Anmeldung der Funktion, in der ich den Speicher wieder frei machen will
        set_new_handler (desborde); //das kümmert sich um die Fehlermeldung wenn der Speicher nicht mehr ausreicht
        long groesse;
        int *dir;
        int nbloque;
        cout << "gewünschte Größe: ";
        cin >> groesse;
        for (nbloque = 1; ; nbloque++)
        {
            dir = new int[groesse];
            cout << "Zuweisung Block-Nummer: " << nbloque <<
            endl;
        }
    speicher_befreien(dir);
    return 1;
    }
    
    void desborde()
    {
        cout << "Speicher nicht ausreichend" << endl;
        exit(1);
    }
    
    int speicher_befreien(int *dir) // hier möchte ich den Speicher wieder frei machen am Ende des Programmes
    {
        delete [] dir;
        return 1;
    }
    

    Ist das jetzt soweit richtig?
    Oder müsste ich im Hauptprogramm die Funktion mit

    speicher_befreien(int *dir)
    

    aufrufen?



  • Stimmt meine Idee für die Speicherfreimachung eigentlich?



  • Wie gesagt lies dir lieber paar Tutorials für Anfänger durch, da gibt es soviele. Allerdings bezweifle ich das das Programm einwandfrei laufen würde, somal mir da von anfang an das hier ins Auge springen würde

    [cpp]
    for (nbloque = 1; /* Condition ?*/; nbloque++)
    {
    dir = new int[groesse];
    cout << "Zuweisung Block-Nummer: " << nbloque <<
    endl;
    }
    [/cpp]

    dort ist gar keine Abbruchbedingung, womit die for-Schleife zur Endlosschleife wird. Damit würdest du dir immer und immer wieder einen neuen Speicherbreicht zuweisen, ohne diesen wieder frei zu geben, würd mal sagen nach ca. 5Sek. gibts nen ordentlichen Fehler.

    Lg Tobi



  • Was is denn das hier für eine englisch-französisch-deutsche Mischkatastrohpe 🙂

    Zum Thema "Speicher_befreien"

    Der Aufruf ( jetzt mit Adressoperator )

    Speicher_befreien( &dir );
    

    Die Funktion ( mit ** )

    int speicher_befreien(int **dir)
    {
        delete [] (*dir);
        return 1;
    }
    

    Sollte so eigentlich funzen... habs aber nicht getestet.

    Ich rate dir das gleiche wie die anderen: Das Tutorial, was du benutzt ist scheinbar nicht nur mehr-sprachig sondern auch noch katastrophales Ansi-C/C++ Mischmasch-krempelzeugs. Es sagt keiner was dagegen, wenn du C-Funktionen nimmst, wenn sie wirklich Sinn machen. Aber der Code, den du da hast, ist vom Stil her eher C, als C++. new und delete sind dann aber wieder C++....

    Entscheide dich für eins von beiden und dann zieh das konsequent durch.

    Und nimm ein anderes Tutorial 🙂



  • Barcelona schrieb:

    Stimmt meine Idee für die Speicherfreimachung eigentlich?

    Nein. Davon abgesehen, dass speicher_befreien(dir) wegen der Endlosschleife nie erreicht wird, würde es sowieso nur den zuletzt angeforderten Speicherbereich freigeben, auch wenn die Schleife eine Abbruchbedingung hat.



  • It0101 schrieb:

    Was is denn das hier für eine englisch-französisch-deutsche Mischkatastrohpe 🙂

    Zum Thema "Speicher_befreien"

    Der Aufruf ( jetzt mit Adressoperator )

    Speicher_befreien( &dir );
    

    Die Funktion ( mit ** )

    int speicher_befreien(int **dir)
    {
        delete [] (*dir);
        return 1;
    }
    

    Sollte so eigentlich funzen... habs aber nicht getestet.

    Ich rate dir das gleiche wie die anderen: Das Tutorial, was du benutzt ist scheinbar nicht nur mehr-sprachig sondern auch noch katastrophales Ansi-C/C++ Mischmasch-krempelzeugs. Es sagt keiner was dagegen, wenn du C-Funktionen nimmst, wenn sie wirklich Sinn machen. Aber der Code, den du da hast, ist vom Stil her eher C, als C++. new und delete sind dann aber wieder C++....

    Entscheide dich für eins von beiden und dann zieh das konsequent durch.

    Und nimm ein anderes Tutorial 🙂

    Das Buch ist auf Spanisch. Ich find' es eigentlich sehr gut zu lesen, es wird aber an vielen Punkten auch auf C bzw den Unterschied zwischen C/C++ eingegangen, vielleicht sind deswegen die Beispiele etwas C lastig...

    Wieso muss ich denn die Funktion

    int speicher_befreien(int **dir)
    

    mit 2 Sternen aufrufen?



  • Barcelona schrieb:

    Wieso muss ich denn die Funktion

    int speicher_befreien(int **dir)
    

    mit 2 Sternen aufrufen?

    Hier wird nichts aufgerufen, hier wird nur etwas anderes für den Aufruf bzw. die Verwendung festgelegt. Du kannst sie erst dann mit dem &-Operator aufrufen:

    speicher_befreien( &dir );
    

    Spricht aber auch nichts dagegen, deine ursprüngliche Version (mit einem * weniger, und beim Aufruf ohne &) zu verwenden.

    MfG,

    Probe-Nutzer



  • Also mit ** hab ichs früher in Ansi-C immer gemacht, wenn ich in einer Funktion was malloccen/realloccen wollte. Muss dann natürlich an allen Ecken und Enden dereferenziert werden... war echt ätzend..


Anmelden zum Antworten