Fehler, aus denen man lernen kann

Mupfel

Mitglied
Ich habe eben wieder einen meiner Lieblingsfehler gemacht. Den möchte ich - in verkürzter Form - mit euch teilen:
Fehlerhafter Code:
#include <cstdint>
#include <iostream>
#include <sstream>
#include <string>

int main(void) {
  std::string s("123 234 456");
  std::uint16_t v1;
  std::uint8_t v2;
  std::uint32_t v3;
  std::stringstream ss(s);
  ss >> v1 >> v2 >> v3;
  std::cout << v3 << v2 << v1 << std::endl;
  return 0;
}
Man könnte meinen, die Ausgabe laute 456234123; sie lautet aber 342124 324123. (Danke an Mat für die Korrektur!)

Und das ist der Hintergrund, in rot13, damit man länger knobeln kann:
Qvr Inevnoyr i2 vfg rva hvag8_g, haq qnzvg rva hafvtarq pune. Qre Fgevatfgernz vagrecergvreg fbzvg ahe qnf refgr Mrvpura qrf Erfg-Fgevatf. i3 raguäyg qnanpu ahe abpu qvr yrgmgra orvqra Mvssrea haq qre yrgmgr Mvssreaoybpx jveq tneavpug refg nhftrjregrg.
 
Zuletzt bearbeitet:
Ich spreche natürlich fließend ROT13, weshalb das kein Problem war. Aber ja, Erklärung ist nachvollziehbar.

Kleiner Tippfehler. Ich kriege 342123 raus

Bash:
#std::cout << v3 << " " << v2 << " " << v1 << std::endl;
./main
342123
34 2 123

Aber ist ja interessant, dass C++ so robust ist und sich flexibel Teile der Blöcke holt, bis alle Variablen "unpacked" sind. Ich hätte gedacht, dass er da den Datentyp overflowed und dann durch die Leerzeichen getrennt zum nächsten Block geht.

So aus Interesse: Was ist der normale Anwendungsfall? Verarbeitung großer Textdateien / roher Sensordaten? Du musst den Input-Daten ja richtig vertrauen, wenn du das einfach so ohne Validierung aufnimmst.
 
Mein Anwendungsfall war dieses Mal ein Prototyp für eine HTTP/1.1-Client-Bibliothek. Dass char als char aus dem Stream geholt werden, auch wenn sie unsigned sind, ist etwas, worüber ich dabei unangenehm gestolpert bin.
Falls hier jemand noch andere Fehler kennt, die schwierig zu finden sind, oder die Anfänger gerne machen: Immer her damit!
Ich werfe noch Folgendes in die Runde: double keinHalb = 1/2 (ist Null wegen Ganzzahldivision).
 
Mir fiel noch ein Fehler ein, den ich mal im Zusammenhang mit der pgsql-Client-Bibliothek gemacht habe. Ich rekonstruiere den mal ungefähr aus der Erinnerung und ohne Test:
C++:
class Blob {
public:
  Blob(char *ptr_, size_t size_);
  ~Blob();

private:
  char *ptr;
  size_t size;
};

Blob(char *ptr_, size_t size_) : size(size_) {
  ptr = new char[size_];
  memcpy(ptr, ptr_, size_);
}

~Blob() { delete[] ptr; }

int main(void) {
  [...] Wrapper.bind([...], Blob([...]));
  [...]
}
Der Destruktor wird also vor dem Aufruf von Wrapper.bind() aufgerufen und somit hat man einen baumelnden Zeiger (dangeling pointer). Das kann dann noch funktionieren und ist schwierig zu finden, wenn man noch unerfahren ist. ("Klappt, klappt nicht, was ist denn das?!")
 
Zurück
Oben Unten