Kopierkonstruktor und Speicherverwaltung



  • Hallo,

    ich gehe gerade ein paar Übungen durch und bei einer weiß ich nicht genau, was das Problem ist bzw. was genau verlangt wird. Hier das Beispiel:

    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    
    using namespace std;
    
    class CFeld {
    	char *p;
    
    public:
    	CFeld(char *s);
    	void drucke() {
    		cout << p << endl;
    	}
    };
    
    CFeld::CFeld(char *s) {
    	p = char[strlen(s) + 1];
    }
    
    int main() {
    	int i;
    	char cp[] = "Feld x";
    	CFeld cfp(cp);
    	return 0;
    }
    

    - Das Programm übersetzt nicht!
    - Ein Fehler, korrigieren!
    - Was könnte eine Warnung erzeugen?

    Das Problem ist bei dieser Zeile p = char[strlen(s) + 1];
    p kann nur char Adresse zugewiesen werden... Wie soll ich das lösen?

    Vielen Dank!


  • Mod

    Die Header <string.h> und <stdlib.h> sind deprecated; nimm die C++-Äquivalente <cstring> und <cstdlib> , wenn überhaupt nötig.
    Warum deklarierst du einen int in der main den du nirgens nutzt?
    Warum setzt du ein C vor deinen Klassennamen?

    CFeld::CFeld(char *s) {
        p = char[strlen(s) + 1];
    }
    

    Ist ausgemachter Unsinn, aus mehreren Gründen:
    - Der Konstruktor will den übergebenen String nicht modifizieren; warum nimmt er aber einen Zeiger auf non-const char ?
    - Der p wurde nirgends anderweitig initialisiert und müsste erst einmal auf gültigen Speicher zeigen. Dann hättest du aber auch Speicherverwaltung am Halse.
    - Der Inhalt muss kopiert werden - mittels strcpy ?
    - Der Code den du da so stehen hast ist völlig unsinnig. Einfach Raten hilft hier nicht!

    C++ ist das sicherlich nicht - eher C mit Klassen. Naja, nicht einmal das.

    Du benötigst std::string . - folgender Code ist ungetestet.

    #include <iostream>
    #include <string> // Das ist der benötigte Header
    
    class CFeld {
        std::string mText;
    
    public:
        CFeld(char const*s);
    
        void drucke() const // verändert nix, daher const
        {
            std::cout << p << '\n'; // Hihi, du willst einen Zeilenumbruch, keinen Zeilenumbruch
        }
    };
    
    CFeld::CFeld(char const*s) :
        mText(s)
    {}
    
    int main()
    {
        char cp[] = "Feld x";
        CFeld cfp(cp);
    } // return-Statement hier überflüssig
    


  • Arcoth schrieb:

    - Der Code den du da so stehen hast ist völlig unsinnig. Einfach Raten hilft hier nicht!

    Wie gesagt, das ist eine Übung bzw. Kontrollfrage. Ich habe das Programm nicht geschrieben. Gegeben ist das Programm und die drei Punkte:
    - Das Programm übersetzt nicht!
    - Ein Fehler, korrigieren!
    - Was könnte eine Warnung erzeugen?
    Ich soll ja das Programm nicht umschreiben, sondern angeblich einen Fehler finden 😃



  • @Arcoth

    Der Code den du da so stehen hast ist völlig unsinnig. Einfach Raten hilft hier nicht!

    Ach, stell dich mal nicht blöder als du bist. Ist doch vollkommen klar was das Programm machen sollte.

    @chris9360
    In welcher Zeile der Fehler ist sagt dir ja der Compiler wenn du versuchst den Code zu übersetzen.

    p = char[strlen(s) + 1];
    

    Das kann schonmal nicht kompilieren.

    Damit ist der "- Das Programm übersetzt nicht!" Teil erledigt.

    Was gemeint ist: fordere ein char-Array an das gross genug ist um den String "s" zu halten, und weise die Adresse dieses neuen char-Arrays "p" zu.

    Du sollst die Zeile jetzt korrigieren, so dass da gültiger C++ Code steht der das macht was ich gerade beschrieben habe.
    Tip: Dazu reicht es diese Zeile minimal anzupassen.

    Damit ist der "- Ein Fehler, korrigieren!" Teil erledigt.

    Damit sollte das Programm dann mal kompilieren. (*)

    Und dann noch zu "- Was könnte eine Warnung erzeugen?" ein kleiner Tip: guck dir die main() Funktion an. Da steht was, was überhaupt komplett sinnfrei ist. Ist zwar gültiges C++, aber wie gesagt vollkommen sinnfrei. So eindeutig und klar sinnfrei, dass manche Compiler dafür ne Warning generieren.
    Was könnte das sein?

    ----

    *:
    Sinn macht es damit immer noch nicht, denn um Sinn zu machen müsste dann noch der Inhalt des übergebenen Strings "s" in das neu erzeugte Array kopiert werden.
    Das wird lustigerweise in der Aufgabenstellung nicht erwähnt - k.A. ob das Absicht oder ein Oversight ist oder was auch immer.

    Und um dann "wirklich" Sinn zu machen, fehlen noch einige Dinge, wie z.B. der Destruktor in dem der Speicher wieder freigegeben wird, ein Copy-Konstruktor und ein Assignment-Operator.


  • Mod

    Ich habe das Programm nicht geschrieben.

    Das wusste ich nicht. Ich nahm an dass du das Programm auf gut Glück geschrieben hast und nun die Fehler nicht entdecken bzw. korrigieren kannst. (Schließlich hast du das nirgens explizit gesagt - gut, 'hier ist das Beispiel' hätte mir wohl einleuchten können.)

    Ist doch vollkommen klar was das Programm machen sollte.

    Ja, offensichtlich. Wie gesagt - mir war nicht klar dass das Programm nicht von ihm stammt.



  • [quote="hustbaer"]@Arcoth

    Was gemeint ist: fordere ein char-Array an das gross genug ist um den String "s" zu halten, und weise die Adresse dieses neuen char-Arrays "p" zu.

    Du sollst die Zeile jetzt korrigieren, so dass da gültiger C++ Code steht der das macht was ich gerade beschrieben habe.
    Tip: Dazu reicht es diese Zeile minimal anzupassen.

    In dieser Zeile

    p = char[strlen(s) + 1];
    

    Steht bei diesem Beispiel

    p = char[7];
    
    strlen(s) + 1
    

    müsste ja ein konstanter Wert sein.
    So funktioniert es

    char a[7];
    p = a;
    

    😞



  • Ich habe es:

    p = new char[strlen(s) + 1];
    

  • Mod

    chris9360 schrieb:

    Ich habe es:

    p = new char[strlen(s) + 1];
    

    Ich wette, du hast nun ein Speicherloch eingebaut. Aber vermutlich interessiert das den Aufgabensteller gar nicht, weil er es selber nicht versteht. Schade, dass so ein Müll heutzutage noch als C++ gelehrt wird 😞 .



  • @SeppJ
    Ich hoffe mal dass das in der Übung dann als nächstes kommt.
    Man kann ja nicht alles auf einmal lehren/lernen.


Anmelden zum Antworten