Problem bei Zeigererhöhung



  • Hallo,

    ich habe folgendes Problem das ich ein Feld in ein anderes kopieren möchte und dabei einmal einen Datensatz überspringen.

    for(int i=0, j=0; j < KontrollObj.AnzKunden; i++, j++) //Feld neu einordnen
    	{
    		if(i == (PosKunde-1))
    		{	
    			j++;
    		}
    		KontrollObj.pKundeFeld[i] = TempKontroll.pKundeFeld[j];
    	}
    

    KontrollObj.pKundeFeld[i] ist um ein Element kleiner als TempKontroll.pKundeFeld[j] (deswegen auch das "überspringen");

    Wenn ich die Felder normal (ohne Zeigererhöhung) kopiere ist das überhaupt kein Problem nur mit bringt er einen AssemblerFehler

    opertor = ist mit

    inline CKunde& CKunde::operator=(const CKunde& Objekt)
    	{
    	if(this == &Objekt)
    		return *this;
    
    	KundenNr = Objekt.KundenNr;
    	Vorname = Objekt.Vorname;
    	Nachname = Objekt.Nachname;
    	Strasse = Objekt.Strasse;
    	Postleitzahl = Objekt.Postleitzahl;
    	Ort = Objekt.Ort;
    	pKonten = Objekt.pKonten;
    	Anz = Objekt.Anz;
    
    	return *this;
    	}
    

    Bitte um Hilfe. Ich versteh diesen Fehler nämlich nicht.



  • Assembler-Fehler hatte ich beim C++-Programieren noch nie. Zeig den doch mal (*hint*)

    Was sind das alles überhaupt für Datenstrukturen? Zeig mal mehr Code. CInteressant cwären cdie CDeklaration cvon CKunde und der Kontext von der Kopieroperation.



  • okay doch kein Assembler Fehler:

    Unbehandelte Ausnahme bei 0x5376EA8E (msvcr110d.dll) in Konto.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xABABABAB

    Kontext:

    Ich hatte einfach die Idee bei einem Feld von Kunden einen Kunden zu löschen.
    Somit Feld kopiert in ein temporäres Feld und neuen speicher allokiert für die benötigte Grösse.
    Dann Feld von Kunden wieder mit temporären Feld füllen, nur dabei den "gelöschten" Kunden auslassen und einfach überspringen.

    Deklaration Kunde;

    //##ModelId=51C1CB0A01A7
    class CKunde
    {
      public:
    
    	//##ModelId=51C7E095010B
    	 void setKundenNr(int Temp){KundenNr = Temp;}
    
    	//##ModelId=51C7E09D03BB
    	 unsigned short getKundenNr(){return KundenNr;}
    
        //##ModelId=51C1CB8303A4
    	void setVorname(string Temp){Vorname = Temp;}
    
        //##ModelId=51C1CB8303AE
    	string getVorname(){return Vorname;}
    
        //##ModelId=51C1CB8303B8
    	void setNachname(string Temp){Nachname = Temp;}
    
        //##ModelId=51C1CB8303C2
    	string getNachname(){return Nachname;}
    
        //##ModelId=51C1CB8303CD
    	void setStrasse(string Temp){Strasse = Temp;}
    
        //##ModelId=51C1CB8303D8
    	string getStrasse(){return Strasse;}
    
        //##ModelId=51C1CB8303E3
    	void setPLZ(string Temp){Postleitzahl = Temp;}
    
        //##ModelId=51C1CB840006
    	string getPLZ(){return Postleitzahl;}
    
        //##ModelId=51C1CB840012
    	void setOrt(string Temp){Ort = Temp;}
    
        //##ModelId=51C1CB84001E
    	string getOrt(){return Ort;}
    
    	//##ModelId=51C7EFCB0091
    	void setGeburtsdatum(DATUM Temp){Geburtsdatum = Temp;}
    
        //##ModelId=51C7EFD4007E
    	DATUM getGeburtsdatum(){return Geburtsdatum;}
    
    	//##ModelId=51C8C8370250
    	void setAnz(int Temp){Anz = Temp;}
    
        //##ModelId=51C8C846001D
    	int getAnz(){return Anz;}
    
    	//##ModelId=51C968B700B8
    	void setpKonten(CKonto* pTemp){pKonten = pTemp;}
    
        //##ModelId=51C968DA003D
    	CKonto* getpKonten(){return pKonten;}
    
        //##ModelId=51CA14D40119
    	CKunde& CKunde::operator=(const CKunde& Objekt);
    
        //##ModelId=51C1CC3A0188
        CKunde();
    
        //##ModelId=51C1CC3A01A7
        virtual ~CKunde();
    
    	//##ModelId=51CA157C02E9
        void setAll(KUNDE Daten, CKonto KontoListe, int AnzahlKonten);
    
        //##ModelId=51CA15A60021
        KUNDE getAll();
    
      private:
        //##ModelId=51C1CB22028F
        string Vorname;
        //##ModelId=51C1CB270221
        string Nachname;
        //##ModelId=51C1CB2B028F
        string Strasse;
        //##ModelId=51C1CB33036B
        string Postleitzahl;
        //##ModelId=51C1CB3A036F
        string Ort;
        //##ModelId=51C7EFBB02AD
        DATUM Geburtsdatum;
    	//##ModelId=51C1DB3E013E
        CKonto* pKonten;
        //##ModelId=51C1E2620248
        int Anz;
        //##ModelId=51C7E07603C9
        int KundenNr;
    
    };
    

  • Mod

    http://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations

    Der naheliegende Verdacht ist, dass du hier irgendwo manuell mit Pointern rumfrickelst. Ich sehe ein paar rohe Pointer in deinem Code, auch wenn du keinen Code zeigst, der mit diesem tatsächlich etwas tut. Superverdächtig ist auf jeden Fall mal:

    pKonten = Objekt.pKonten;
    

    http://en.wikipedia.org/wiki/RAII
    http://en.wikipedia.org/wiki/Smart_pointer
    http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)
    http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap
    2. Ich vermute einen allgemeinen Designfehler, durch dessen Behebung Ratschlag Nummer 1 überflüssig wird. Wo leben die Konten?
    3. http://en.wikipedia.org/wiki/Special_member_functions



  • Okay da muss ich nochmal genau sehen wie ich das beheben kann.

    Es wundert mich nur das das sonst funktioniert, nur eben bei dem speziellen Fall zusammen bricht.



  • CKopierst cdu csonst can cirgendeiner CStelle CKunden? CWenn cder CKopierkonstruktor cnur cdort caufgerufen cwird, cdann csollte cdie CSache cklar csein.

    Wie sehen denn Zuweisungsoperator und Destruktor aus? Rufst du irgendwo "delete pKonten" (ggf. mit "[]") auf?

    Was genau ist pKonten überhaupt? Ein dynamisches Array? Ein einzelnes Objekt? Wo wird das erzeugt und wer kümmert sich darum, dass es ordnungsgemäß gelöscht wird?



  • Gut Ich habe es nochmal kontrolliert und nun funktioniert alles wie gedacht.
    Ich Habe mich in ein oder 2 Positionen von Pointern vertan.

    Trotzdem großen dank an die schnellen Antworten.



  • Die Klasse sieht verdächtig generiert aus. Zumal der Wink mit dem Scheunentor von daddy_felix wahrscheinlich nicht angekommen ist.

    Die Klasse verwendet ein using namespace im globalen Namensbereich der Headerdatei. Mach das nie, nie, nie. Nein, niemals!

    Zumal const-correctness vollkommen ignoriert wurde (bitte recherchieren und so früh wie möglich anwenden).

    Der Fehler mit den wilden (pösen pointern) kannst Du von vorneherein ausschließen, wenn Du einen Container verwendest. Nach der Namensgebung handelt es sich um eine Liste (Sequenz) von Kontenobjekten. std::vector wäre hier angebrachter (wenn Person das Konto besitzt).

    Die vielen getter und setter riechen auch irgendwie nach Blähcode. Man sollte nicht zu jedem Attribut ein getter/setter schreiben.

    Ave



  • Ja das ganze muss wohl nochmal überarbeitet werden.

    Das rumspielen mit den Pointern ist dem geschuldet das wir solche Strukturen nicht benutzen dürfen, ansonsten hätte ich die Möglichkeiten schon seit anfang an genommen.



  • Ich seh schon: Ein Lehrbeispiel fernab jeglicher Realität 😉

    Ave


Anmelden zum Antworten