Probleme bei Rückgabe eines Objectes nach binärer Operatorüberladung
-
Grüsst euch,
ich bin gerade dabei einen Vektor selbst zu implementieren, in dem eine Zahlenfolge, repräsentiert jeweils durch eine Stelle im Vektor, sich befindet. Ein Beispiel:
456 + 3596
(vec1) (vec2)Nun gehört der plus operator überladen, welches die beiden Vektoren addiert. Es klappt alles eigentlich bis auf die Rückgabe auf vecres.
mVector vecres; if (43 == (int)op){ //do addition vecres = *vecfst + *vecsnd; vecres.print(); }else if (45 == (int)op){ //do subtraction vecres = *vecfst - *vecsnd; }Deklaration der Überladung vom + Operator:
friend mVector operator+(const mVector &sum, const mVector &sum2);
Das Problem ist nun, dass vecres nach der überladung kein Daten mehr beinhaltet, da im allerletzten Schritt bei der Überladung vom + Operator (nachdem der Copy-Konstruktor geladen wurde) nochmals der Dekonstruktor auf vecres geladen wird (nachdem er bereits davor auf result (rückgabe im + operator) angewandt worden ist).
Ich weiß da nicht mehr weiter wo der Fehler sein könnte. Der Einfeinheithalber habe ich unter rapidshare das ganze Projekt upgeloaded. Wäre sehr dankbar, wenn mir jemand sagen könnte wie man das Problem lösen kann.
-
Du hast den operator= nicht überladen, als Faustregel gilt, wenn du einen der folgenden Drei implementieren musst, dann musst du alle implementieren: Kopierkonstruktor, Zuweisungsoperator, Destruktor.
-
Besten dank, soweit habs geklappt. Musste nur den = Operator überladen

Nur gibts mit dem dynamisch erzeugten Objekt "mVector vecres" Probleme. Beim verlassen der Schleife, wo dieses erzeugt wurde, wird der Dekonstruktor vom Vektor aufgerufen. Soweit verständlich. Nur dort gibts dann folgende Exception:
Windows has triggered a breakpoint in Übung1.exe.
This may be due to a corruption of the heap, and indicates a bug in Übung1.exe or any of the DLLs it has loaded.
The output window may have more diagnostic information
//Constructor mVector::mVector(void) { // init the vector m_pArray = new char[m_Alloc]; assert(NULL != m_pArray); // abort if no memory m_Len = 0; m_Size = m_Alloc; }//Destructor mVector::~mVector(void) { delete[] m_pArray; // kill the vector }Kann mir ehrlich gesagt nicht vorstellen wo da ein Fehler sein sollte
-
Vermutlich ist deine Implementierung des Zuweisungs-Operators oder des Copy-Konstruktors fehlerhaft. Im Zweifelsfall mal herzeigen.
Im Übrigen ist das hier
assert(NULL != m_pArray); // abort if no memoryvollkommen sinnlos. Die new Anweisung in der Zeile davor kann keinen Null-Zeiger zurückgeben.
-
Diese Abfrage hat mein Prof so in seinen Sampels implementiert - müsste schon stimmen was er sagt.
//Copy-Constructor mVector::mVector (const mVector &mvec) { m_pArray = new char[mvec.m_Size]; assert (NULL != m_pArray); // abort if no memory memset(m_pArray,0,mvec.m_Size); for (int i = 0; i < mvec.m_Len; i++){ m_pArray[i] = mvec[i];} m_Len = mvec.m_Len; m_Size = mvec.m_Size; }mVector mVector::operator= (const mVector &vec) { if (this != &vec) { delete (m_pArray); m_pArray = new char (vec.m_Size); assert(NULL != m_pArray); // abort if no memory memset(m_pArray,0,vec.m_Size); for (int i = 0; i < vec.m_Len; i++){ m_pArray[i] = vec[i];} m_Len = vec.getLength(); m_Size = vec.getSize(); } return *this; }Kann mir nicht vorstellen, dass da ein Fehler ist. Aber ist möglich...... c++ kann brutal sein

-
Das hier:
delete (m_pArray);geht so nicht. Auf new[] folgt immer ein delete[]. Das der Code nicht Exception-Sicher ist, sei mal nur am Rande erwähnt.
Und die Abfrage auf den Null-Zeiger ist überflüssig. Sag deinem Prof, daß er keine Ahnung hat.
Edit:
Und das geht so auch nicht:
m_pArray = new char (vec.m_Size);Eckige Klammern bitte!
-
thx - jetzt läufts
-> scheiß Klammern vertauscht
Und beim Lesen siehste des auch netWegen Assert werde ich mal im Inet gleich mal gucken

-
hmmm......
http://en.wikipedia.org/wiki/Assertion_(computing)
Comparison with error handling
It is worth distinguishing assertions from routine error handling. Assertions should be used to document logically impossible situations — if the "impossible" occurs, then something fundamental is clearly wrong. This is distinct from error handling: most error conditions are possible, although some may be extremely unlikely to occur in practice. Using assertions as a general-purpose error handling mechanism is usually unwise: assertions do not allow for graceful recovery from errors, and an assertion failure will often halt the program's execution abruptly. Assertions also do not display a user-friendly error message.Consider the following example of using an assertion to handle an error:
int *ptr = malloc(sizeof(int) * 10);
assert(ptr != NULL);
// use ptr
Here, the programmer is aware that malloc may return a NULL pointer if memory could not be allocated. This is possible: the operating system does not guarantee that every call to malloc will succeed, and the program should be prepared to handle the failure. An assertion is probably not the best choice here, because a malloc failure is not logically impossible — it is a legitimate possibility, albeit not one that will arise very often in practice. The assertion in this example does serve one useful purpose, however: it documents that the programmer has deliberately decided not to provide robust error handling for memory allocation failures.
-
-
Oder zum Beispiel das hier:
http://www.cprogramming.com/tips/showTip.php?tip=64&count=30&page=0
Merke: new ist nicht malloc!
-
ich sehe es thx. Vielleicht ists bei C so, dass new 0 zurückliefert falls kein Speicher allokiert werden konnte
-
In C gibt es kein new. Da gibt es wie gesagt malloc und das kann in der Tat 0 zurückgeben.
-
Chmielewski schrieb:
ich sehe es thx. Vielleicht ists bei C so, dass new 0 zurückliefert falls kein Speicher allokiert werden konnte
Dein Professor hat früher mal VS6 benutzt und von dem auf C++ geschlossen, ein sehr beliebter Irrtum.
Ein Tipp: Kauf dir das Buch "OOP für Dummies" damit du die Grundregeln für C++ kennen lernst.
Ein op= implementiert man normalerweise mit dem Kopierkonstruktor.