Mit Verwendung von pointer->funktion Speicherzugriffsfehler



  • Hi
    hab folgendes Problem habe zwei Klassen z.B

    class a
    {
    public:
            funktiona(){pB->funktionb();};
    private:
            b *pB;
    }
    
    class b
    {
    public:
           funktionb();
    private:
    
    }
    b::funktionb()
    {
    vector<int>vectorb;
    cout<<"Gibt zahl ein"<<endl;
    cin>>zahl;
    vectorb.pushback(zahl);
    ....
    }
    

    wenn ich die Funktion b mit dem Hilfe des Pointers pB aufrufe läuft die Funktion b problemlos durch doch am ende der Funktion kommt die Fehlermeldung (error: Speicherzugriffsfehler)

    ich weiß das es einfacher gehn würde wenn ich in der Klasse A einfach ein objekt der klasse b erzeuge und dann die funktion aufrufe aber ich würde gern wissen wie ich das mit dem pointer lösen kann, denn irgendwie muss das ja auch funktionieren
    danke im voraus 🙂



  • Selbstverständlich kann man eine Funktion einfach per Pointer aufrufen! Du machst einen Fehler in dem Code, den du nicht zeigst (wobei selbst der gezeigte Code offensichtlich nichts mit dem Original zu tun hat).



  • Zeigt der Pointer pB überhaupt auf ein valides Objekt der Klasse b?



  • okj es handelst sich um ein Lottospiel wo bei in Klasse Ziehung die Zufallszahlen gezongen werden. Und in Lotto dann wieder verwendet werden.

    class Lotto 
    {	
    public:
            ...
    	void ziehen();
    	 Lotto();
    	~Lotto();
    private:
    	Ziehung *pzieh;
    
    };
    void Lotto::ziehen()
    {   		
    	pzieh->ziehen();
    
    }
    class Ziehung
    {	
    public:
    	void ziehen();
    	void ergebnisAusgeben();
    	std::vector<int>gezogene_zahlen;
    private:
    
    };
    void Ziehung::ziehen()
    {
    //bestimmt ihre 6 Lottozahlen
    int i =0;
    int zahlen[49];
    int zufallszahl[6];
    int r;
    
    while (i < 6)
    {
    	cout << "bestimme zahl" << i+1 << endl;
    		do
    		{
    			srand(time(NULL)* time(NULL)); 
    			r = rand()%48+1;
    
    		}while (zahlen[r] == 1);
    			zahlen[r] = 1;
    			zufallszahl[i] = r+1;
    			i++;
    
    }
    //die gezogenen Zahlen sotieren und ausgeben
    for (int x=0; x<6; x++)
    {
    	for (int y=0; y<5; y++)
    	{
    		if (zufallszahl[y] > zufallszahl[y+1])
    		{
    			int temp = zufallszahl[y];
    			zufallszahl[y] = zufallszahl[y+1];
    			zufallszahl[y+1] = temp;
    		}
    
    	}
    }
    	for (int i=0; i<=5; i++)
    	{
    		cout << "Lottozahl " << i+1 <<": "<< zufallszahl[i]<< endl;
    
    	} 
    
    		  gezogene_zahlen.push_back(zufallszahl[0]);
    		  gezogene_zahlen.push_back(zufallszahl[1]);
    		  gezogene_zahlen.push_back(zufallszahl[2]);
    		  gezogene_zahlen.push_back(zufallszahl[3]);
    		  gezogene_zahlen.push_back(zufallszahl[4]);
    		  gezogene_zahlen.push_back(zufallszahl[5]);
    
    }
    


  • Du könntest es doch mit Vererbung lösen:

    class Lotto : public Ziehung
    {
    ...
    public:
    void Lottoziehen( )
    {
    ziehen();
    }
    };
    

    Die Sache mit dem Pointer klappt auch du must jedoch dann im Konstruktor von Lotto ein Ziehung-Objekt erstellen, damit dein Pointer auch gültig ist.

    MfG



  • Hallo,

    verzichte hier ganz auf Zeiger und verwende einfach

    Ziehung ziehung;
    

    Und dann eben per '.' statt '->' darauf zugreifen...

    P.S: Vererbung halte ich hier für den falschen Weg - m.E. reicht hier eigentlich auch eine Klasse aus (außer man würde noch andere Klassen haben, welche auch auf Ziehung zugreifen).



  • habs jetzt so gelöst:

    void Lotto::ziehen()
    {   		
    	Ziehung *pzieh= new Ziehung;
    	pzieh->ziehe();
    	delete pzieh;	
    }
    

    aber wenn ich jetzt dann das Ergebnis ausgeben möchte hab ich wieder einen Fehler
    // report an out_of_range error

    void Lotto::ergebnisAusgeben(void)
    {
    	Ziehung *pzieh = new Ziehung;
    	Tippzettel *tipp = new Tippzettel;
    	Tippzettel *tipp1 = new Tippzettel;
    	Tippzettel *tipp2 = new Tippzettel;
    	unsigned int i=0;
    if(getTippzettelanzahl()==1)
    {
    	sort(pzieh->gezogene_zahlen.begin(),pzieh->gezogene_zahlen.end());
    	sort(tipp->getippte_zahlen.begin(),tipp->getippte_zahlen.end());
    	vector<int> intersec;
    	set_intersection(pzieh->gezogene_zahlen.begin(), pzieh->gezogene_zahlen.end(), tipp->getippte_zahlen.begin(), tipp->getippte_zahlen.end(), back_inserter(intersec));
    	cout<<tipp->adresse.at(0)<<endl;
    	cout<<tipp->adresse.at(1)<<endl;
    	cout<<tipp->adresse.at(2)<<endl;
    	cout<<"Die getippte Zahlen waren: "<<tipp->getippte_zahlen.at(0)<<" "<<tipp->getippte_zahlen.at(1)<<" "<<tipp->getippte_zahlen.at(2)<<" "<<tipp->getippte_zahlen.at(3)<<" "<<tipp->getippte_zahlen.at(4)<<" "<<tipp->getippte_zahlen.at(5)<<" "<<endl;
    	cout<<"Es stimmen folgende Zahlen ueberein: ";
    
    		 if( i<intersec.size())
    		 {
    			cout << " " << intersec.at(i);
             }else
    			 cout<<"Es stimmen keine Zahlen ueberein"<<endl;
    }
    delete pzieh;
    delete tipp;
    delete tipp1;
    delete tipp2;
    }
    

  • Mod

    😕 Warum legst du scopelokale Objekte mit new an, anstatt, äh, scopelokal?

    Kommst du von Java? Das Schlüsselwort new kannst und solltest du in C++ bis auf wenige Ausnahmen komplett vergessen. Dann ist der Code auch gleich viel, viel, viel weniger fehleranfällig.



  • naja mit new hat er mir wenigstens kein speicherzugriffsfehler geschmissen was wäre denn eine alternative?


  • Mod

    Ziehung zieh;
    


  • danke aber ich würde es gerne mit Pointer lösen



  • Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

    was hat den dieser fehler zu bedeuten?



  • wennoder schrieb:

    danke aber ich würde es gerne mit Pointer lösen

    Und warum?
    Ich würde auch gerne mit meinem Traktor zur Arbeit fahren, nur dauert das immer so lange...



  • naja interesse halber
    wenn es die Möglichkeit gibt das mit Pointer zu lösen würde ich diese gerne kennen



  • ???

    Ziehung z;
    Ziehung* pz = &z;
    ...
    

    Wenn du unbedingt auf den Pointer bestehst mach's so.

    MfG


  • Mod

    wennoder schrieb:

    naja interesse halber
    wenn es die Möglichkeit gibt das mit Pointer zu lösen würde ich diese gerne kennen

    Irgendeine Möglichkeit mit rohen Pointern gibt es schon, man muss es bloß richtig machen. Die saubere Methode, wenn man doch mal wirklich Pointer braucht, ist diese so weit wie möglich zu verstecken. In einer Klasse die nach RAII-Design aufgebaut ist. Das sollte man vielleicht einmal im Leben selber gemacht haben (also google mal, was das bedeutet), ansonsten benutzt man je nach Verwendungszweck die Container/Smartpointer aus der Standardbibliothek, die genau das machen.



  • yihaaa schrieb:

    Ziehung z;
    Ziehung* pz = &z;
    ...
    

    Wenn du unbedingt auf den Pointer bestehst mach's so.

    MfG

    okj hab das jetzt so geändert aber wenn ich die funktion

    void Lotto::ergebnisAusgeben(void)
    {
    	/*Tippzettel *tipp = new Tippzettel;
    	Tippzettel *tipp1 = new Tippzettel;
    	Tippzettel *tipp2 = new Tippzettel;
    	Ziehung *pzieh= new Ziehung;
    	Ziehung z; 
    	Ziehung* pzieh = &z;
    	Tippzettel t;
    	Tippzettel *tipp = &t;
    	Tippzettel *tipp1 = &t;
    	Tippzettel *tipp2 = &t;*/
    
    	unsigned int i=0;
    if(getTippzettelanzahl()==1)
    {
    	sort(pzieh->gezogene_zahlen.begin(),pzieh->gezogene_zahlen.end());
    	sort(tipp->getippte_zahlen.begin(),tipp->getippte_zahlen.end());
    	vector<int> intersec;
    	set_intersection(pzieh->gezogene_zahlen.begin(), pzieh->gezogene_zahlen.end(), tipp->getippte_zahlen.begin(), tipp->getippte_zahlen.end(), back_inserter(intersec));
    	cout<<tipp->adresse.at(0)<<endl;
    	cout<<tipp->adresse.at(1)<<endl;
    	cout<<tipp->adresse.at(2)<<endl;
    	cout<<"Die getippte Zahlen waren: "<<tipp->getippte_zahlen.at(0)<<" "<<tipp->getippte_zahlen.at(1)<<" "<<tipp->getippte_zahlen.at(2)<<" "<<tipp->getippte_zahlen.at(3)<<" "<<tipp->getippte_zahlen.at(4)<<" "<<tipp->getippte_zahlen.at(5)<<" "<<endl;
    	cout<<"Es stimmen folgende Zahlen ueberein: ";
    
    		 if( i<intersec.size())
    		 {
    			cout << " " << intersec.at(i);
             }else
    			 cout<<"Es stimmen keine Zahlen ueberein"<<endl;
    }
    

    bekomme ich folgende fehlermeldung

    Unbehandelte Ausnahme bei 0x012b6dd4 in OOAD.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xccccccd4.
    

    und werde darauf hingewiesen

    iterator end()
    {	// return iterator for end of mutable sequence
    		return (iterator(this->_Mylast, this));
    		}
    


  • SeppJ schrieb:

    Möglichkeit mit rohen Pointern gibt es schon, man muss es bloß richtig machen. Die saubere Methode, wenn man doch mal wirklich Pointer braucht, ist diese so weit wie möglich zu verstecken. In einer Klasse die nach RAII-Design aufgebaut ist. Das sollte man vielleicht einmal im Leben selber gemacht haben (also google mal, was das bedeutet), ansonsten benutzt man je nach Verwendungszweck die Container/Smartpointer aus der Standardbibliothek, die genau das machen.

    die Smartpointer schau ich mir jetzt mal an


Anmelden zum Antworten