Fehlerhafte Klasse



  • Hallo zusammen,

    ich lerne zurzeit C++ und versuche Aufgaben zu lösen. Hier ist jedoch eine Aufgabe, die ich nicht verstehe. Könntet Ihr mir eventuell eine Tipps geben, wo der Fehler sein könnte? 🙂

    Also es sind die Klassen sinuswerte.hpp, sinuswerte.cpp und die Datei main.cpp vorhanden, wobei bei der Klasse Sinuswerte ein Fehler existiert, der zu finden ist. Dieser Fehler soll gefunden und korrigiert werden.

    Hier die Klassen bzw. Datei:

    sinuswerte.hpp
    #ifndef SINUSWERTE_HPP
    #define SINUSWERTE_HPP

    class Sinuswerte
    {
    private:
    int anzahl;
    double* werte;
    public:
    Sinuswerte(int anzahl);
    double sin(double x);
    };

    #endif

    sinuswerte.cpp
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include "sinuswerte.hpp"

    Sinuswerte::Sinuswerte(int anzahl)
    : anzahl(anzahl)
    {
    werte = new (std::nothrow) double[anzahl];
    if (!werte) {
    std::cout << "Zu wenig Speicher verfuegbar." << std::endl;
    std::exit(1);
    }

    for (int i = 0; i < anzahl; ++i) {
    werte[i] = std::sin(i*2*M_PI/anzahl);
    }
    }

    double Sinuswerte::sin(double x)
    {
    int i = (int)(x*anzahl/2/M_PI) % anzahl;
    if (i < 0) i += anzahl;
    return werte[i];
    }

    main.cpp
    #include <iostream>
    #include "sinuswerte.hpp"

    int main()
    {
    for (int i = 0; i < 100000000; ++i) {
    Sinuswerte* sinuswerte = new Sinuswerte(100);
    sinuswerte􀀀>sin(0.3456);
    delete sinuswerte;
    }
    }

    Ich wäre dankbar für jeden Tipp. 🙄

    MfG und Danke im Voraus



  • In Anbetracht der Tatsache, dass in der main ein paar Millionen Instanzen davon erzeugt werden wird wohl gemeint sein, dass sie keinen Destruktor hat.



  • Genau das ist das zu lösende Problem. Ich soll ohne eine Änderung der main-Funktion und des Konstruktors diesen Fehler beheben.

    Ich verstehe im Allgemeinen jedoch nicht, was in der main-funktion bezweckt ist.
    Nach meinen Verständnis erfolgt folgendes:

    1. Es werden 100000000 mal ein Array von Sinuswerten der Länge 100 deklariert.
    2. Dann wird die Funktion sin(0.3456) aufgerufen, der im Grunde immer ein bestimmtes Element des Arrays zurückgibt, ohne diese zu ändern.
    3. Anschließend wird das erzeugte Array sinuswerte einfach gelöscht.

    Verstehe ich das Programm falsch? Wenn das Array mithilfe des Befehls delete bei jedem Scleifendurchlauf gelöscht wird, entsteht doch kein Memory-Leak oder?

    LG
    Markus



  • Markus97 schrieb:

    Genau das ist das zu lösende Problem. Ich soll ohne eine Änderung der main-Funktion und des Konstruktors diesen Fehler beheben.

    und das tust du, indem du einen Destruktor hinzufügst und darin den angeforderten Speicher wieder freigibst.



  • Markus97 schrieb:

    Verstehe ich das Programm falsch? Wenn das Array mithilfe des Befehls delete bei jedem Scleifendurchlauf gelöscht wird, entsteht doch kein Memory-Leak oder?

    Das Array wird aber nicht gelöscht. Bei jedem Schleifendurchlauf in der main wird die Klasse und im Konstruktor ein array mit new erstellt, welches aber nie wieder gelöscht wird aufgrund des fehlenden Destruktors.



  • Ich hatte folgenden Destruktor definiert:

    Sinuswerte::~Sinuswerte(){
    	delete[] werte;
    }
    

    Jedoch bestand das Problem weiterhin. Grund dafür ist glaube ich, dass man zuerst die individuellen Objekte freigeben muss, bevor das Array gelöscht wird.

    Sinuswerte::~Sinuswerte(){
    
    	 for (int i = 0; i < anzahl; ++i){
    		delete werte[i];
    	 }
    	delete[] werte;
    }
    

    Doch auf diese Weise erhalte ich ein Problem:
    error: invalid type argument of unary '*' (have 'double'), expected pointer



  • Markus97 schrieb:

    Ich hatte folgenden Konstruktor definiert:

    Sinuswerte::~Sinuswerte(){
    	delete[] werte;
    }
    

    Das ist auch ganz richtig so.

    Markus97 schrieb:

    Jedoch bestand das Problem weiterhin.

    Welches Problem? Hier war bis jetzt immer nur die Rede von "einem Fehler". Bekommst du eine Fehlermeldung vom Compiler?



  • Zu jedem new gehört ein delete, deshalb ist der erste Destruktor richtig (du hast ja nirgens sowas wie 'werte[123] = new irgendwas'.

    Du hast geschrieben

    Markus97 schrieb:

    1. Es werden 100000000 mal ein Array von Sinuswerten der Länge 100 deklariert.
    2. Dann wird die Funktion sin(0.3456) aufgerufen

    In dem Code den du zeigst, passiert da nacheinander. Ist der Code hier anders, als der, mit dem du arbeitest?



  • Ich erhalte keinen Compiler-Fehler. Jedoch läuft das Programm leider bei der Ausführung ohne ein Ende zu nehmen, was ich verhindern möchte.



  • Markus97 schrieb:

    Ich erhalte keinen Compiler-Fehler. Jedoch läuft das Programm leider bei der Ausführung ohne ein Ende zu nehmen, was ich verhindern möchte.

    Ohne ein Ende ist mit diesem Code (anzahl der durchläufe, berechnungen, ...) in ordnung (es wird Enden, irgendwann...)
    Was du verhindern solltest ist dieser

    std::cout << "Zu wenig Speicher verfuegbar." << std::endl;
    

    fehler, und das hast du mit dem Destruktor erledigt.



  • hi lerne auch grad privat c++ und wollte mal fragen ob du auch privat lernst, oder wegen ausbildung/studium. und wenn ausbildung/studium, in welchem jahr du bist



  • Markus97 schrieb:

    Ich erhalte keinen Compiler-Fehler. Jedoch läuft das Programm leider bei der Ausführung ohne ein Ende zu nehmen

    Vielleicht dauert es einfach eine Weile? Verkleiner doch mal die Zahl der Schleifendurchläufe auf was handlicheres.



  • Danke sehr, hat geklappt. Nun kann ich das nächste Thema in C++ beginnen. 🙂


Anmelden zum Antworten