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; };
-
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