delete und pointer- Frage



  • Hallo zusammen,

    folgende Zeilen:

    struct FRIEND {
    	char* name;
    	long tel;
    };
    
    //1.
    int countFriends_zeiger(FRIEND* pF);
    //2.
    int compareFriends(FRIEND pF, FRIEND pF);
    
    FRIEND* pF = new FRIEND;
    
    int main()
    {
    	//1.
    	pF->name = "Alfons"; pF->tel = 11;
    	(pF + 1)->name = "Egon"; (pF + 1)->tel = 22;
    	(pF + 2)->name = "Johannes"; (pF + 2)->tel = 33;
    	(pF + 3)->name = "Willi"; (pF + 3)->tel = 44;
    	(pF + 4)->name = "Xanthippe"; (pF + 4)->tel = 55;
    	(pF + 5)->name = "Zeratul"; (pF + 5)->tel = 66;
    	(pF + 6)->name = '\0'; (pF + 6)->tel = '\0';
    	//2.
    	FRIEND f1; f1.name = pF->name; f1.tel = pF->tel;
    	FRIEND f2; f2.name = (pF + 1)->name; f2.tel = (pF + 1)->tel;
    
    	//1.
    	cout << "//1." << endl;
    	cout << "anzahl: " << countFriends_zeiger(pF) << endl;
    	//2.
    	cout << "\n//2.\ncompareFriends = " << compareFriends(f1, f2) << endl;
    
    	/*delete f;		//IN BEARBEITUNG
    	f = 0;*/
    
    	cin.get();
    	return 0;
    }
    

    1. Warum funktioniert hier "delete f;" nicht so wie es soll? Wie müsste es richtig aussehen?

    Und nochmal das gleich, diesmal nur mit ** anstatt von *:

    struct FRIEND {
    	char* name;
    	long tel;
    };
    
    //1.
    int countFriends(FRIEND** f);
    //2.
    int compareFriends(FRIEND* f1, FRIEND* f2);
    
    FRIEND** f = new FRIEND*;
    
    int main()
    {
    	//1.
    	(*f)->name = "Alfons"; (*f)->tel = 11;
    	(*(f + 1))->name = "Egon"; (*(f + 1))->tel = 22;
    
    	cout << "name: " << (*f)->name << ", tel: " << (*f)->tel << endl;
    	cout << "name: " << (*(f + 1))->name << ", tel: " << (*(f + 1))->tel << endl;
    
    	/*//1.
    	cout << "\ncountFriends(f) = " << countFriends(f) << endl;*/
    
    	/*delete f;		//IN BEARBEITUNG
    	f = 0;*/
    
    	cin.get();
    	return 0;
    }
    

    2. Warum funktioniert meine Übergabe der Daten nicht richtig? Wie müsste es richtig aussehen?
    (Es funktioniert schon, jedoch stürtzt mein Programm nach dem ausgeben ab, bzw es hängt sich auf.)

    Vielen Dank für eure Hilfe und Eure Zeit.



  • Im ersten Code hast du (wie es aussieht) keine Variable namens f und kannst sie deshalb auch nicht im Operator delete verwenden. Im ersten Code greifst du auch auf Speicher zu, der dir nicht gehört und das endet im UB (für nur ein Element allokiert aber auf die folgende sechs (nicht bestehenden) zugegriffen. Und wenn du Zeiger auf Literale machst, sollte das Ziel des Zeigers konstant sein (oder du verwendest direkt std::string ). Allgemein ist das direkte Verwenden von new / delete und ihre Array-Freunde nicht schön und sollte einem Container vorenthalten werden.

    Ps: #include <iostream> und using namespace std; im ersten Code vergessen

    EDIT:
    1. Darf ich fragen, wieso du überhaupt etwas auf dem Heap speichern willst?
    2. long als Telefonnummer ist nicht ideal



  • Danke für deine schnelle Antwort.

    "#include <iostream> und using namespace std; im ersten Code vergessen"
    ... Ich habe es nur einfach nicht mit kopiert. 😉

    Sollten neue Fragen aufkommen, melde Ich mich wieder.



  • Auf deine Frage: Weil uns vorgegeben wurde, das Problem so zu lösen.

    So, Ich habe mein erstes Programm nun angepasst.

    delete pF;
    	pF = 0;
    

    1. Jedoch hängt sich mein Programm nun bei jedem 2. / 3. mal starten auf. Kannst du mir das etwas genauer erklären? Ich auch nicht wie es nun anders aussehen sollte.

    2. Die Frage zum zweiten Code, warum Ich name und tel nicht richtig besetzen kann, steht immer noch. Auch wenn du der Meinung bist, dass dies hier nicht "schön" ist, kannst du mir vielleicht trozdem zeigen, wie es richtig aussehen sollte?



  • Weil im Unterschied zu erstem Code du hier überhaupt kein einziges Element hast.

    struct Foo
    {
        int a;
        int b;
        int* dummerPointer;
    };
    
    int main()
    {
        // Ein Foo-Objekt wird erzeugt.
        // In den Variablen «a», «b» und «dummerPointer» steht nur Müll drin.
        Foo aufDemStack;
    
        aufDemStack.a = 1;
        aufDemStack.b = 2;
        aufDemStack.dummerPointer = new int( 5 );
    
        // Wenn die Variable «aufDemStack» den Scope verlässt wird
        // alles bis auf «aufDemStack.dummerPointer» zestört,
        // da es auf dem Heap erzeigt wurde.
    
        Foo* aufDemHeap; // Pointer zeigt ins Nirvana.
        aufDemHeap->a = 2;  // BOOM!!
    
        // Der Pointer zeigt auf etwas Existierendes.
        // «aufDemHeap.dummerPointer» zeigt aber nach wie vor ins Nirvana.
        aufDemHeap = new Foo;
    
        // Die Variable zeigt auf den „nächsten“ Foo. Blöd das es keins mehr gibt.
        Foo*  sollteMannOderFrau_NIE_NIE_Tun = aufDemHeap + 1;
    
        Foo* fooArray = new Foo[ someValue ]; // Array von Foos.
    
        // Hier kann man auf alle Elemente von fooArray
        // 0 bis someValue - 1 zugreifen.
    
        for ( size_t i = 0; i < someValue; ++i )
        {
            fooArray[ i ].a = 0xDEAD; // Arrayzugriff.
            ( fooArray + i )->b = 0xDEADEAD; // Pointerzugriff
        }
    
        //...
        //...
    
        delete aufDemHeap;
        delete[] fooArray;
    
        // Alle dynamische Foo-Objekte wurden gelöscht.
        // Achtung! falls irgendwo die «dummerPointer» erzeugt wurden
        // gibst es jetzt einen Memleak.
    
        Foo** crazyComPointer;  // Pointer auf Pointer.
        *crazyComPointer = new Foo; // Wir haben die Adresse von Pointer auf dynamisch erzeigtes Foo.
        ( *crazyComPointer )->a = 5;
        Foo** crazyComArray2;
         ( * crazyComArray2 ) = new Foo[ someValue ]; // Och.
    
        // Alles löschen. Alles ganz schnell vergessen. Lehrer ignorieren!
    }
    


  • Floppy212121 schrieb:

    So, Ich habe mein erstes Programm nun angepasst.

    delete pF;
    	pF = 0;
    

    Wenn das deine einzigen Anpassungen sind, ist das Programm noch immer so etwas von verkehrt, und verwendet uninitialisierte Speicherbereiche.

    struct FRIEND {
        char* name;
        long tel;
    };
    

    1. name ist nur ein Zeiger, hier fehlt noch einiges (z.B. Alloziation/Freigabe).
    2. C-Strings kannst du nicht den Inhalt durch Zuweisung setzen [name = "Egon" ist hier z.B. verkehrt], sondern musst die C-Funktionen strcpy und Co verwenden.

    FRIEND** f = new FRIEND*;
    

    Ähm... ich hoffe du weißt was du tust... wobei ich eben das nicht glaube.

    delete pF;
      pF = 0;
    

    Zu guter Letzt: Das 0-Setzen eines Zeigers macht nur Sinn, wenn er nochmals verwendet werden soll.

    Mit C++ hat das Programm aber so gut wie gar nichts zu tun.



  • Floppy212121 schrieb:

    1. Jedoch hängt sich mein Programm nun bei jedem 2. / 3. mal starten auf. Kannst du mir das etwas genauer erklären? Ich auch nicht wie es nun anders aussehen sollte.

    Ganz anders natürlich! Aber bevor ich dazu mehr sage ein paar Gegenfragen: Wer bringt Dir C++ bei? Ist das eine Übung, die du machen sollst? Wenn ja, wieviel Gestaltungsspielraum hast Du da? Was ist die genaue Fragestellung? Wenn nicht: Möchtest Du C++ richtig lernen?



  • ... geloest, vielen Dank für eure Hilfe ... jk

    MfG


Anmelden zum Antworten