mini Quellcode mit Anfängerfehler



  • Hi Leute,

    leider steh ich mit C++ noch am Anfang. Bis jetzt hab ich alle Probleme schnell per www (auch Euer Forum war hilfreich!) ausmachen können. Jetzt mach ichs mir ein bissl komplizierter und schon gehts nimmer so leicht....naja...

    Folgendes hab ich aufgrund eines c++-Buches angenommen: Ich dachte, der Standard-ctor belegt alle Variablen einer Klasse mal mit Null. Wofür gilt das genau? Pointer und deren Zieladressen zB?
    Also da unten hab ich ein bissi Code geschrieben, der nichts macht als einen meiner Fehler zu erzeugen. Er stürzt zur Laufzeit ab. Vielleicht könnt ihr mir sagen woran es liegt. Das Problem liegt in der Zuweisung der in insert übergebenen Variable. Per Debugger (MS Visual C++) sehr ich auch, dass wert und next keine Werte haben...also nicht null, nicht irgendeine komische Hex-Zahl...keinen Wert.

    Mit besten Grüßen
    Andi

    #include<iostream.h>
    
    class List {
    private:
    	class Node {			
    		public:
    		char wert;		
    		Node* next;		
    	};
    public:	
    	Node *root;
    
    	void insert(char c){
    		root->wert=c;
    	};
    
    };
    
    void main(){
    	List test;
    	test.insert('a');
    };
    

    Danke!



  • gast0815 schrieb:

    Folgendes hab ich aufgrund eines c++-Buches angenommen: Ich dachte, der Standard-ctor belegt alle Variablen einer Klasse mal mit Null. Wofür gilt das genau? Pointer und deren Zieladressen zB?

    Das stimmt eben nicht. Werte sind nicht definiert, manche Compiler tun dies für Zeiger aber nur im Debug Modus.
    Du musst mindestens root und next initialisieren



  • gast0815 schrieb:

    Folgendes hab ich aufgrund eines c++-Buches angenommen: Ich dachte, der Standard-ctor belegt alle Variablen einer Klasse mal mit Null.

    Diese Annahme ist ein Irrtum und wenn das so oder so ähnlich aus deinem Buch
    hervorgehen sollte, was ich mal nicht hoffe, dann wirf es besser weg. Du musst
    in deinem von dir selbst geschriebenem Konstruktor deine Variablen selbst
    initialisieren, das macht keiner für dich.

    C++ ist nicht Java. 😃

    gast0815 schrieb:

    #include<iostream.h>
    
    class List {
    private:
    	class Node {			
    		public:
    		char wert;		
    		Node* next;		
    	};
    public:	
    	Node *root;
    
    	void insert(char c){
    		root->wert=c;
    	};
    
    };
    
    void main(){
    	List test;
    	test.insert('a');
    };
    

    Es ist im allgemeinen keine "gute Idee" die Daten deiner Objekte direkt
    zugreifbar zu machen. Also mach bitte aus root ein "private member".



  • Redhead schrieb:

    gast0815 schrieb:

    Folgendes hab ich aufgrund eines c++-Buches angenommen: Ich dachte, der Standard-ctor belegt alle Variablen einer Klasse mal mit Null.

    Diese Annahme ist ein Irrtum

    Wie kommst Du darauf? Die Annahme ist korrekt. Nicht-initialisierte Variablen einer Klasse werden mit Nullwerten initialisiert (genauer gesagt: dem Standard-Konstruktor).



  • Konrad Rudolph schrieb:

    Redhead schrieb:

    gast0815 schrieb:

    Folgendes hab ich aufgrund eines c++-Buches angenommen: Ich dachte, der Standard-ctor belegt alle Variablen einer Klasse mal mit Null.

    Diese Annahme ist ein Irrtum

    Wie kommst Du darauf? Die Annahme ist korrekt. Nicht-initialisierte Variablen einer Klasse werden mit Nullwerten initialisiert (genauer gesagt: dem Standard-Konstruktor).

    Die eingebauten Datentypen haben keinen Standardkonstruktor.



  • bluecode schrieb:

    Die eingebauten Datentypen haben keinen Standardkonstruktor.

    Ah?

    #include <iostream>
    
    int main()
    {
        int i = int();
        std::cout << i << std::endl;
    }
    


  • Dann pack doch mal dein i in ne klasse und versuchs. Da kommt bei mir nicht 0 aus.



  • ...und versuch das mal mit nem Zeiger 🙄



  • bluecode schrieb:

    Dann pack doch mal dein i in ne klasse und versuchs. Da kommt bei mir nicht 0 aus.

    Habe ich. 🙂

    Zugegeben, ich habe geschummelt: Ich habe die Klasse explizit initialisiert:

    #include <iostream>
    
    struct Test {
        char* c;
        int i;
        float f;
    };
    
    int main(int argc, char* argv[])
    {
        using namespace std;
    
        Test foo = Test();
        cout << foo.i << endl << (int)foo.c << endl << foo.f << endl;
    }
    


  • Zeigefinger schrieb:

    ...und versuch das mal mit nem Zeiger 🙄

    Ja, und wo soll da das Problem sein?

    // [...]
    int* i = new int();
    cout << i << endl << *i << endl;
    delete i;
    

    Gibt mir sowas aus:

    00356078
    0
    


  • Den Zeiger direkt mit Heap zu befüllen war nicht gefordert!

    Und

    int* i = int*();
    

    will nicht so recht klappen :p



  • Konrad Rudolph schrieb:

    Zugegeben, ich habe geschummelt: Ich habe die Klasse explizit initialisiert

    Stimmt, wenn man das explizit macht, (scheint) es zu funktionieren... verwundert mich ein wenig 🤡 , aber ob das jetzt die Lösung ist? Ich weiß nicht... ich würd/werd lieber explizit den konstruktor aufrufen und nicht blind darauf vertrauen, dass ich mich beim Benutzen der Klasse noch daran erinner 😃



  • LordJaxom schrieb:

    Den Zeiger direkt mit Heap zu befüllen war nicht gefordert!

    Ach so, habe ich falsch verstanden.

    LordJaxom schrieb:

    Und

    int* i = int*();
    

    will nicht so recht klappen :p

    Doch, wieso nicht?! Die ganze STL baut doch darauf auf, dass man Basistypen konstruieren kann ...

    typedef int* T;
    int* pi = T();
    

    Klappt wunderbar.



  • #include <iostream> //iostream.h ist veraltet!
    
    using namespace std; //das zeug aus iostream und das andere standard-zeug ist im namespace std
    
    template<typename T>
    class List
    {
        class Node
        {
        public:
            Node(T value) : m_value(value), m_next(0) {} //konstruktor mit initialisierungsliste
            T m_value;
            Node *m_next;
        };
    
        Node *m_first, *m_last;
    
    public:
        List() : m_first(0) {} //konstruktor mit initialisierungsliste
        ~List() { clear(); }
    
        void clear()
        {
            Node *current;
            while(m_first)
            {
                current = m_first;
                m_first = m_first->m_next;
                delete current;
            }
        }
    
        void append(T value)
        {
            if(!m_first)
                m_last = m_first = new Node(value);
            else
                m_last = m_last->m_next = new Node(value);
        }
    
        void show()
        {
            for(Node *current = m_first; current != 0; current = current->m_next)
                cout << current->m_value << endl;
        }
    };
    
    int main()
    {
        List<char> test;
        test.append('a');
        test.append('b');
        test.append('c');
    
        test.show();
    }
    


  • int* pi;
    std::cout << pi << "\n" << *pi << "\n";
    

    *päng*

    Sein Ursprungsproblem war ein nicht initialisierter Zeiger, und die Zeigen nicht per Default auf NULL, jedenfalls müssen sie das nicht. Sprich: Undefiniertes Verhalten!



  • Konrad Rudolph schrieb:

    typedef int* T;
    int* pi = T();
    

    Klappt wunderbar.

    Klar doch, aber willst Du einen Anfänger wirklich gleich mit typedefs erschlagen? 🤡


Anmelden zum Antworten