Fragen und Kommentare zur 6. Vorlesung / zum 6. Übungsblatt
@Fabian: Wenn ich den Test auf meinem Rechner laufen lasse, kommt auch ein Fehler in StringTest.insert. Auch bei Value of: s1[4] aber Actual: '|. Das deutet darauf hin, dass Sie an irgendeiner Stelle etwas dem Zufall überlassen, d.h. da wo ein bestimmtes Zeichen stehen sollte, steht das, was da gerade zufällig im Speicher stand. Hannah 9Jun10 2:04 Ich habe ein Problem mit Hudson, und zwar läuft dort ein Test nicht ganz so wie er soll. Bei mir auf dem PC läuft der Test ohne Fehler durch, Hudson meldet jedoch Mein Account ist ff1 @Dominik: Man kann den Destruktor schon so aufrufen, aber wie Roman richtig sagt, sollte man das nicht tun. Einzige Ausnahme ist wenn man einen Test für den Destruktor schreibt. Wie ich übrigens für meine Musterlösung für das 6. Übungsblatt getan habe. @Dominik: Den Destruktor solltest du (fast) nie manuell aufrufen. Kopier die betreffenden zwei Zeilen halt in eine neue Methode reset(), clear() o.Ä. Bzgl 'const': Du übergibst ja der insert() bzw. append() Methode das String-Objekt s was du einfügen bzw. anhängen willst. Dafür musst du lediglich die Zeichen von s auslesen können, aber nichts am Zustand von s ändern. (Du fügst die Zeichen von s ja in das aufrufende Objekt ein und nicht umgekehrt) @Hannah: Das mit dem @Roman: Deine Antwort habe ich leider nicht verstanden: --- Du musst an dem übergebenen String Objekt nichts ändern, da du es ja nur in das Objekt, das das String Objekt übergeben kriegt, einfügst. (Deswegen also const) --- Bitte minimal genauer... Dominik 08Juni 22:43 @Hannah: Ich meinte auch eher AutoComplete bei Methoden, da hat man in einem größeren Projekt dann oft viele Vorschläge, die bei Verwendung von this wegfallen. Bzgl. "_": Man verwendet halt mit this ein language feature, und "_" ist halt erstmal nicht selbsterklärend. Wer z.b. einen PHP-Background hat verbindet mit "_" die Kennzeichnung von privaten Membervariablen. Aber letztendlich ist es wohl doch zum größten Teil geschmackssache @Roman: Bin gerade auch überfragt, ob die @Hannah: Vielleicht nicht unbedingt üblich, aber oft sinnvoll bzw. manchmal sogar nötig (s. Templates). Die "_" Konvention für Membervariablen verliert z.B. (meiner Meinung nach) ihren Sinn durch die Existenz von this, da man so explizit zwischen Member- und lokaler Variable unterscheiden kann. Auch funktioniert AutoComplete bei den meisten Editoren mit this um einiges besser @Dominik: Ja, genau, wie Roman sagt @Dominik: 1. Du musst an dem übergebenen String Objekt nichts ändern, da du es ja nur in das Objekt, das das String Objekt übergeben kriegt, einfügst. (Deswegen also const) 2. this.append(s) innerhalb einer Klasse funktioniert nicht, this ist ja ein Pointer auf die "aktuelle" Instanz, d.h. du musst ihn entweder dereferenzieren, d.h. (*this).append oder "->" verwenden, d.h. this->append (was letztendlich das gleiche ist). @Dominik: Daran lags leider net. Sonst hätte er ja nur nen fehlgeschlagenen Test angezeigt. Es muss ja was mit der Adressierung zu tun haben. Mich verwundert nur, dass alles beim direkten Aufruf funktioniert, aber dasselbe bei den Testfehlen gleich solch einen Fehler erzeugt. Ich versuche bei @Jan: Dein Test-Index ist falsch. Der Aufruf bedeutet imo dass _anstelle_ von Position 4 im Array der zweite String eingebettet werden soll. Somit klappt das bis s1[2] noch, aber dann sollte es sein: Ich habe folgendes Problem bei der Insert-Funktion: Und zwar bekomm ich beim Test folgende Fehlermeldung: Das Merwürdige ist nur, wenn ich Insert mit denselben Parametern über die Main-Datei starte, funktioniert alles wunderbar. Hier der Testfall und der Aufruf über die Main: Das merkwürdige ist, dass es für Testfälle bis Startposition = 2 funktioniert. Wäre über jeden Hinweis dankbar. @Kevin: Sehr schwer, da so abstrakt (ohne den Code zu sehen) was zu zu sagen. Versuchen Sie doch einmal bei einem Tutor vorbei zu schauen, der kann Ihnen dann sicher helfen. Oder wenn Sie es selber machen wollen, setzen Sie an strategischen Stellen Hallo, nochmal zu meinem Problem von gestern: Ich habe alle Indizes überprüft und mir ausgeben lassen, kann aber nirgends einen Fehler feststellen. Jetzt habe ich in meinem Test einam ldie find methode rausgenommen, dann funktioniert alles. Dann habe ich die find Methode hineingenommen und die insert Methode nicht mehr getestet, dann klappt auch alles wunderbar! Also irgendwie vertragen sich meine beiden Methoden find und insert nicht! Hat jemand eine Idee, woran das liegen kann? Laeuft wieder alles Kann mich dem Vorredner anschließen, Hudson hat gerade seinen Spaß (Error 403) und ich kann auch nichts updaten/comitten. SVN down? Kann weder updaten, committen noch neu auschecken. Auch Hudson scheiter beim kompilieren alter Übungen. Immer Error 403. @Hannah Vielen Dank für die Hilfe. Es war dann doch nicht die zweite for-Schleife sondern das ";" hinter dem else if (...). Kleiner Fehler, große Wirkung. @Ben: @Dennis: Wenn Sie in Zukunft etwas geadded haben und das rückgängig machen wollen, machen Sie einfach @Dennis: Probier es so, du machst wieder svn update oder ein neuen checkout damit du dieser .svn wiederkriegst. Dann schreib einfach so Ich hab da auch mal ein Problem. Beim Testen der erase-Methode bekomme ich diese schöne Fehlermeldung: Die Programmzeile die diesen Fehler auslöst scheint die zweite for-Schleife zu sein: Es geht um den Fall, das er mitten aus dem String was löschen soll. Er scheint alles richtig einzusetzen/zu löschen und dann ganz am Ende noch irgendwie nen Fehler rauszuhauen. Hab das böse Gefühl, dass ich da seit gestern abend was blödes übersehe. Ich habe ein Problem mit SVN. Ich habe versehentlich die binaries geaddet (aber noch nicht commited). Wie in einem früheren post beschrieben habe ich dann die .svn datei aus dem Ordner gelöscht und wollte den Ordner danach neu adden. Nun bekomme ich jedoch den bekannten fehler "befindet sich bereits unter versionskontrolle", obwohl die .svn in uebungsblatt-6 nicht mehr existiert. Wenn ich jedoch svn delete uebungsblatt-6 ausführe erhalte ich folgende meldung "Verzeichnis »uebungsblatt-6/.svn« mit Administrationsdateien der Arbeitskopie fehlt". @Kevin: Entweder veränderst du in find den Wert von _length, oder die Methode terminiert nicht rechtzeitig (falsche Abbruchbedingung). @Kevin: Offenbar rufen Sie irgendwo in Ihrer Hi, habe ein Problem mit dem Testen der find Methode! Folgender Test: gibt mir den Fehler ASSERT_DEATH testet, ob die Ausführung der Anweisung(en) in den geschweiften Klammern abgebrochen wird (exit, assert-failure usw.), und zwar mit der entsprechenden Fehlermeldung (zweites Argument). @Markus: Sind sie doch längst, und das ungeschnittene AVI auch schon. Das geschnittene WMV kommt morgen. Können Sie noch die Folien der Vorlesung hochladen? @Dario: Zur ersten Frage, siehe mein Beispiel in dem Kommentar über der Der Findmethod soll mir der Abstand zwischen den Start und die nächste char oder wo ganau mein Char in meinem String sich befindet? also ich denke so müsste es stimmen. Außerdem wollte ich wissen ob es Sinn macht , wenn ich so schreiben würde :newEtwas = int new[0] oder newEtwas= char new[0] oder ob man es weglassen kann. Wollte mal auch "off-topic" fragen, was genau eine statische Variable (oder funktion) ist und was ein inline funktion ist. Gruß. @Hannah, SebastianD: Ah, okay, danke. @Sebastian: Ein Objekt kann nicht nur auf seine eigenen private bedeutet Klassen-, nicht Instanzsichtbarkeit. In der Vorlesung wurde Allerdings ist @Martin: Glaube, ich habe da alles richtig gemacht, aber schauen Sie zur Sicherheit nochmal nach. Ich habe auf jeden Fall keine Fehler mit Absicht eingebaut, falls das Ihre Frage war. Muss man die const-Korrektheit auch bei den bereits geschriebenen Methoden überprüfen? @Jens : Danke. Und diese \0 entspricht _list[i] = -1; oder? Aber dies ist nicht bei allen Methoden nötig, da wir bei manchem mit dem _Length das regeln könnnen , oder? außerdem bei insert methode wenn ich aber insert(s, 9999) dann eintippe, was soll dann passieren? einfach mit assert behandeln oder denselben " abcdefg"String ausgeben? @Dario: Wie bei den integer Listen auf dem letzten Blatt muss man einem Array irgendwie mitteilen, wo es zuende ist. @Jens: Kannst du ein Beispiel machen? muss ich immer diese termienierende 0 betrachten, wenn mein String ein andere Länge hat? @Dario: Wenn newlength nicht die Laenge von _string ist, dann fehlt im buf vielleicht die terminierende 0? Hallo, warum wenn ich beim EraseMethod so schreibe: also nach dieser Methode versuche ich was zu erasen aber habe bemerkt , dass dann die Charachter nicht mehr gleich sind , sondern anders.( wenn ich mein Erase Methode mit ein For oder While Schleife implementiere..) Gruß @Anonymous: Donnerwetter, das ist mir neu, was schon was heißen will. Herzlichen Dank für den Hinweis. Weil mich verwundert hat, dass p = NULL; delete p; durchlief, habe ich kurz recherchiert. delete p ist wohl laut C++ Standard für p = NULL wohl definiert. Ich denke, das gilt dann auch für delete[]. Es scheint erwünscht zu sein, nicht auf NULL zu prüfen. http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.8 @Sebastian: In der Tat ein Widerspruch, sorry, habe es jetzt korrigiert. Es liegt daran, dass ich die Musterlösung für das 5. Übungsblatt und die In der punkte-vergabe.txt steht: @Hannah: Habs gerade eben getestet. Problem ist leider nicht behoben :(. @David: Ja, das Skript für die Konfiguration unseres SVN Servers wurde gestern geändert, und ich sehe gerade, dass es da noch Fehler gibt. Habe es für Sie jetzt gerade von Hand korrigiert, schauen Sie mal ob es jetzt bei Ihnen klappt. Ich habe auch Jens Hoffmann und Axel Lehmann informiert, die das tieferliegende Problem dann hoffentlich bald beheben. Ich hab folgendes Problem: Ich kann nichts mehr auf SVN hochladen, da ich jedes mal die Fehlermeldung (403 Forbidden) >>teaching/cplusplus-ss2010/!svn/ver/3021/dz23<< bekomme... Hatte sonst nie Probleme mit SVN und jeder Versuch hat nicht funktioniert (cleanup, update neues Arbeitsverzeichnis, .svn-Ordner löschen). Woran kann das liegen? @David: Nein, einen assert failure direkt kann man nicht testen, brauchen Sie auch nicht. @Ben: Das liegt an Ihrer Arbeitskopie. Sie haben vermutlich einen anderen Ordner mitsamt dem Gibt es irgendeine Möglichkeit, Kann es sein, dass das SVN nicht ordnungsgemäß funktioniert? Denn ich möchte gerne meine Aufgabe hochladen, bekomme aber jedesmal svn: warning: 'uebungsblatt-6' is already under version control. @Hannah: Alles klar, vielen Dank. Habe ich bereits vermutet, aber bevor ich vielleicht was ganz wichtiges nicht mitbekommen habe, dachte ich, dass ich besser nochmal nachfrage @David: Yup, es sollte andersrum da stehen, und "xxx" sollte ein String Objekt meinen, das diese Zeichenkette repräsentiert. Habe es jetzt umgeschrieben, machen Sie einfach Kann es sein, dass sich ein Fehler bei @Mirko + Alle: Gute Frage, ich habe selber gerade die Musterlösung für die Aufgabe geschrieben und habe es wie folgt gehandhabt. Bei Hi, wie sollen wir den Fall bei erase(..) behandeln wenn start negativ ist, (und auch der Fall wenn length negativ ist). Man könnte bei erase(-10,12) ja z.b. die ersten beiden Zeichen löschen. Und bei erase(5,-3), die Zeichen an den Stellen 5,4,3. Oder dürfen wir in diesen Fällen einen Fehler ausgeben / den String unverändert lassen. @Alle: Habe gerade noch eine Destruktor + Test zu meinem Code aus @Simson + Alle: Ja, da gab es gerade Probleme, aber laut Jens Hoffmann sollte jetzt wieder alles gehen. Die Dateien von der Vorlesung heute habe ich bereits hochgeladen. Die svn-Ordner der Vorlesungsdateien und Musterlösungen sind gesperrt? [ RUN ] StringTest.insert
StringTest.cpp:100: Failure
Value of: s1[4]
Actual: '�' (4294967205, 0xFFFFFFA5)
Expected: 'o'
Which is: 'o' (111, 0x6F)
[ FAILED ] StringTest.insert (0 ms)
s1.insert(var, 4);
ASSERT_EQ('d', s1[3]);
ASSERT_EQ('x', s1[4]);
Dominik 08Juni 18:22 *** glibc detected *** ./StringTest: munmap_chunk(): invalid pointer: 0x09843ac8 ***
String s1;
String var;
var.set("xxx");
s1.set("abcdefg");
s1.insert(var, 4);
ASSERT_EQ('a', s1[0]);
ASSERT_EQ('b', s1[1]);
ASSERT_EQ('c', s1[2]);
ASSERT_EQ('x', s1[3]);
__________________________
String var;
var.set("xxx");
s1.set("abcdefg");
s1.insert(var, 4);
printf("%c\n", s1[0]);
printf("%c\n", s1[1]);
printf("%c\n", s1[2]);
printf("%c\n", s1[3]);
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
make: *** [test] Fehler 134
else if (_length > (start + length));
{
int newLength = _length - length;
char* newString = new char[newLength];
for (int i = 0; i < start; ++i) newString[i] = _string[i];
for (int i = start; i < newLength; ++i) newString[i] = _string[i + length];
if (_string != NULL) delete[] _string;
_string = newString;
_length = newLength;
}
TEST(StringTest, find)
{
String s1;
s1.set("abcdefgabc");
ASSERT_EQ(0, s1.find('a',0));
}
StringTest: String.cpp:46: char String::operator[](int) const: Assertion `i <= _length' failed.
Aborted
make: *** [test] Fehler 134
TEST(StringTest, squareBracketOperator)
{
String s;
s.set("abc");
ASSERT_DEATH({s[-1];},
".*");
ASSERT_DEATH({s[3];},
".*");
ASSERT_EQ('a', s[0]);
ASSERT_EQ('b', s[1]);
ASSERT_EQ('c', s[2]);
}
sb.set("a12345a2");
ASSERT_EQ(0, sb.find('a', 0));
ASSERT_EQ(0, sb.find('a', 6);
void String::append(const String& s)
{
assert(_string != NULL || _length == 0);
int newLength = _length + s._length;
// Insert the given string into this string at the given position. For
// example, if this string is "abcdefg" and s represents the string "xyz",
// then after an insert(s, 3), this string should be "abcxyzdefg".
Dario 04Mai10 12:09 string1: "Ich bin ein String\0"
string2: "Ein zweiter String.\0"
solange i < 5: string2[i] = string1[i]
Ohne terminierende 0 ist dann:
string2: "Ich zweiter String.\0"
Mit 0 nach der while schleife, waere:
string2: "Ich b\0" wie es sein sollte.
while ( i < newlength)
{
buf[a] = _string[i];
++i;
++a;
}
...
SebastianS 3Jun10 19:47
.