Fragen und Kommentare zur 6. Vorlesung / zum 6. Übungsblatt
Edit conflict - other version:
Laeuft wieder alles Jens 08 Jun 14:54
Kann mich dem Vorredner anschließen, Hudson hat gerade seinen Spaß (Error 403) und ich kann auch nichts updaten/comitten. Norman 08 Jun 14:35
Edit conflict - your version:
End of edit conflict
SVN down? Kann weder updaten, committen noch neu auschecken. Auch Hudson scheiter beim kompilieren alter Übungen. Immer Error 403. Alex 08 Jun 10 14:18
@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. BenN 8Jun10 13:50
@Ben: std::bad_alloc deutet auf einen Fehler in einer Ihrer Anweisungen mit new. Machen Sie einmal vor jede Anweisung mit new ein printf, das die Größe des Feldes, das Sie da jeweils allozieren wollen, ausgibt, und schauen Sie mal was da kommt. Vielleicht wollen Sie ja irgendwo ein Feld mit negativer Größe allozieren, oder Größe null, oder Größe zehn hoch zehn. Hannah 8Jun10 13:14
@Dennis: Wenn Sie in Zukunft etwas geadded haben und das rückgängig machen wollen, machen Sie einfach svn revert <file names>. Ihre Arbeitskopie ist jetzt vermutlich ziemlich durcheinander, am einfachsten ist es in dem Fall an anderer Stelle neu auszuchecken, zu schauen was Sie dann dort haben, und da dann ggf. Dateien aus dem alten Ordner rüber zu kopieren (aber nur einzelne Dateien). Oder Sie gehen zu einem Tutor, der sich mit SVN auskennt, und versuchen gemeinsam Ihre Arbeitskopie wieder zu reparieren. Hannah 8Jun10 13:11
@Dennis: Probier es so, du machst wieder svn update oder ein neuen checkout damit du dieser .svn wiederkriegst. Dann schreib einfach so svn add uebungsblatt-6 --force. Müsste es schon klappen. Dario 7Jun10 12:42
Ich hab da auch mal ein Problem. Beim Testen der erase-Methode bekomme ich diese schöne Fehlermeldung:
terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc Aborted make: *** [test] Fehler 134
Die Programmzeile die diesen Fehler auslöst scheint die zweite for-Schleife zu sein:
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; }
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. BenN 8Jun10 12:39
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". Dennis 8Jun 12:36
@Kevin: Entweder veränderst du in find den Wert von _length, oder die Methode terminiert nicht rechtzeitig (falsche Abbruchbedingung). SebastianD 7Jun10 18:31
@Kevin: Offenbar rufen Sie irgendwo in Ihrer find Methode den operator[] auf (d.h. sie machen xxx[i] für irgendein String Objekt und einen Index i), und bei diesem Aufruf ist der Index größer als die _length von dem string. Hannah 7Jun10 18:30
Hi, habe ein Problem mit dem Testen der find Methode! Folgender Test:
TEST(StringTest, find) { String s1; s1.set("abcdefgabc"); ASSERT_EQ(0, s1.find('a',0)); }
gibt mir den Fehler
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]); }
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). .* ist dabei ein Platzhalter für eine beliebige Zeichenfolge, wenn ich das richtig sehe. Weitere Infos gibts in der gtest-Dokumentation. HINWEIS: Unbedingt jedes ASSERT_DEATH in zwei Zeilen aufspalten, da linter nur ein ";" pro Zeile erlaubt. Fabian 5Jun10 14:33
@Markus: Sind sie doch längst, und das ungeschnittene AVI auch schon. Das geschnittene WMV kommt morgen. Hannah 4Jun10 22:07
Können Sie noch die Folien der Vorlesung hochladen? Markus 4Jun10 21:58
@Dario: Zur ersten Frage, siehe mein Beispiel in dem Kommentar über der find Funktion in der String.h. Es ist die absolute Position des nächsten Vorkommens bei oder nach start. Zur zweiten Frage: = new int[0] ist nicht sinnvoll und sollte vermieden werden. Ich bin auch im Moment überfragt, was der memory allocator da macht, aber es ist ja auch egal, Sie können dann mit dem Zeiger den Sie zurückbekommen ja eh nichts anfangen. Zu dritten Frage: eine statische Membervariable ist eine, die für alle Objekte der Klasse gleich ist, also quasi eine Konstante der Klasse. Bei inline geht es um eine Verbesserung der Laufzeit des ausführbaren Programms, sonst nichts. Dazu werden wir aber wohl erst am Ende der Veranstaltung kommen. Solange wir noch nicht überall auf schnelle Laufzeit achten, und das tun wir im Moment überhaupt noch nicht, macht es keinen Sinn über inline zu sprechen. Hannah 4Jun10 21:25
Der Findmethod soll mir der Abstand zwischen den Start und die nächste char oder wo ganau mein Char in meinem String sich befindet?
sb.set("a12345a2"); ASSERT_EQ(0, sb.find('a', 0)); ASSERT_EQ(0, sb.find('a', 6);
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ß. Dario 4Juni 21:01
@Hannah, SebastianD: Ah, okay, danke.
@Sebastian: Ein Objekt kann nicht nur auf seine eigenen private Membervariablen zugreifen, sondern auch auf die private Membervariablen von allen anderen Objekten vom selben Typ. Hannah 4Jun10 20:40
private bedeutet Klassen-, nicht Instanzsichtbarkeit. SebastianD 4Jun10 20:39
In der Vorlesung wurde String::append ja so geschrieben:
void String::append(const String& s) { assert(_string != NULL || _length == 0); int newLength = _length + s._length;
Allerdings ist _length ja eigentlich private; wie kommt es also, dass wir dennoch darauf zugreifen können (s._length)? Müsste man die Funktionen/Variablen nicht erst untereinander als friend deklarieren? SebastianS 4Juni 20:34
@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. Hannah 4Jun10 14:13
Muss man die const-Korrektheit auch bei den bereits geschriebenen Methoden überprüfen? MartinG 04Jun10 14:05
@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
// 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".
wenn ich aber insert(s, 9999) dann eintippe, was soll dann passieren? einfach mit assert behandeln oder denselben " abcdefg"String ausgeben?
Dario 04Mai10 12:09
@Dario:
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.
Wie bei den integer Listen auf dem letzten Blatt muss man einem Array irgendwie mitteilen, wo es zuende ist. Jens 3Jun10 11:05
@Jens: Kannst du ein Beispiel machen? muss ich immer diese termienierende 0 betrachten, wenn mein String ein andere Länge hat? Dario 3Jun10 10:48
@Dario: Wenn newlength nicht die Laenge von _string ist, dann fehlt im buf vielleicht die terminierende 0? Jens 3Jun10 9:36
Hallo, warum wenn ich beim EraseMethod so schreibe:
while ( i < newlength) { buf[a] = _string[i]; ++i; ++a; } ...
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ß Dario 3Jun10 9:27
@Anonymous: Donnerwetter, das ist mir neu, was schon was heißen will. Herzlichen Dank für den Hinweis. Hannah 3Jun10 21:52
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 Anonymous 3Jun10 21:15
@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 punkte-vergabe.txt diesmal erst sehr spät (zwei Wochen nach Erstellen des Übungsblattes) fertig gemacht habe. Es soll Ihnen aber natürlich nicht zum Nachteil gereichen, wenn irgendjemand dadurch Punkte abgezogen wurden bitte beim Tutor melden mit Verweis auf diese Bemerkung von mir. Hannah 3Jun10 20:34
In der punkte-vergabe.txt steht: * Der Test für popBack sollte den Grenzfall enthalten, dass die Liste leer ist (dann -1 zurück), sonst 1/2 Punkt Abzug. In dem Übungsblatt steht jedoch, dass man dann einen assert failure werfen soll? Kann ich mich nur nicht daran erinnern, wie man assert_failures testet, oder gibt es da einen Widerspruch? SebastianS 3Jun10 19:47
@Hannah: Habs gerade eben getestet. Problem ist leider nicht behoben :(. DavidZ 3Jun10 15:46
@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. Hannah 3Jun10 15:40
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? DavidZ 3Jun10 15:19
@David: Nein, einen assert failure direkt kann man nicht testen, brauchen Sie auch nicht. Hannah 3Jun10 14:50
@Ben: Das liegt an Ihrer Arbeitskopie. Sie haben vermutlich einen anderen Ordner mitsamt dem .svn Ordner mitkopiert. Löschen Sie den .svn Ordner in Ihrem Ordner uebungsblatt-6 und dann sollte es klappen. Hannah 3Jun10 14:49
Gibt es irgendeine Möglichkeit, assert failure zu testen? DavidZ 3Jun10 14:48
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. Ben 3Jun10 14:42
@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 Z 2Jun10 22:14
@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 svn update. Hannah 2Jun10 22:10
Kann es sein, dass sich ein Fehler bei insert in der Header Datei eingeschlichen hat? Beim Tip steht ja insert(3, "xxx") was an sich schon keinen Sinn macht, da ja eigentlich links der String steht und rechts die Startposition ist. Ist es überhaupt möglich, die Methode so aufzurufen (also mit der anderen Richtung)? Da ja String hier eine Klasse ist, kann ich doch nicht einfach einen Text als Übergabewert nehmen, oder? David Z 2Jun10 21:52
@Mirko + Alle: Gute Frage, ich habe selber gerade die Musterlösung für die Aufgabe geschrieben und habe es wie folgt gehandhabt. Bei erase müssen start und length beide >= 0 sein, ich habe dafür jeweils ein assert am Anfang der Methode. Ich finde negative Werte für diese Argumente machen nicht wirklich Sinn bzw. der Sinn wäre zu weit hergeholt. Sonst ist aber alles erlaubt, also sowohl dass der start erst am oder nach dem Ende des strings kommt (dann wird einfach nichts gelöscht) und dass start + length bis über den string hinausgeht (dann wird halt von start bis zum Ende des strings gelöscht). Diese Randfälle sollten natürlich alle in dem Test für diese Methode berücksichtigt werden. Bei insert habe ich sowohl einen assert(start >= 0) also auch einen assert(start <= _length) weil alles andere keinen Sinn macht. Hannah 2Jun10 21:42
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. Mirko 2Jun10 21:21
@Alle: Habe gerade noch eine Destruktor + Test zu meinem Code aus vorlesung-6 hinzugefügt, also wenn Sie den schon bei sich runtergeladen haben, machen Sie ein svn update. Hannah 2Jun10 20:05
@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. Hannah 2Jun10 19:54
Die svn-Ordner der Vorlesungsdateien und Musterlösungen sind gesperrt? Simson 2Jun10 18:55