Unerklärliche out_of_range in string::substr

Habe ich immer eine wirklich lästige Fehler über eine std::out_of_range bei Aufruf der substr. Der genaue Fehler ist

kündigen, genannt nach dem werfen ein
instance of 'std::out_of_range'

what(): basic_string::substr

Ich bin absolut sicher, dass tmp_request hat eine Länge größer als 1. Egal was ich pass auf substr—1, 2, oder bodypos—es wirft immer diesen Fehler. Ich bin mit g++ auf Unix.

Einzige interessante Sache, die ich einschließen kann, ist der string hat mehrere "\r\n", darunter eine "\r\n\r\n".

In einer cpp-Datei:

std::string tmp_request, outRequest;

tmp_request = SS_Twitter->readData();
outRequest = SS_Twitter->parse(tmp_request);

In einem anderen:

 std::string parse(const std::string &request)
 {
  std::map<std::string,std::string> keyval;
  std::string outRequest;
  if(request[0]=='P')
  {
   if(request.find("register")!=std::string::npos)
   { //we have a register request
    size_t bodypos = request.find("username");
    if(bodypos==std::string::npos) 
    {
     HttpError(400,"Malformed HTTP POST request. Could not find key username.",request); 
    }
    else
    {
     std::string body = request.substr(bodypos);
     StringExplode(body,"&", "=",keyval);
     outRequest = "doing stuff";
    }

   }

Update:

std::string request2("P\r\nregister\r\nusername=hello\r\n\r\n");

std::string body = request2.substr(4);

Wirft den gleichen Fehler. Jetzt weiß ich, das ist absolut gültigen und korrekten code, aber es ist immer noch wirft den Fehler.
//entfernt Quelle-link

  • Ok der code ist zwar nicht sauber. Aber konzentrieren wir uns auf die Fehler bitte?
  • Ob oder ob nicht etwas ist ein bug der selten eine Meinung, wenn es um Sprache geht. Sollten Sie bezweifle, dass eine solche primitive Funktion hat einen bug in der Implementierung, da Sie sonst verfangen Sie sich auf die falsche Sache. Die Tatsache, Sie halten beibehalten Ihren code richtig ist und die Umsetzung ist irgendwie falsch, wird nie Ihr problem lösen. Offensichtlich haben Sie einen logischen Fehler irgendwo; Sie müssen die lassen Sie Ihre Annahmen und starten Sie frisch.
  • Haben Sie versuchen, Ihren code sauber, und sehen, ob Fehler erneut Auftritt? Vielleicht das der Grund.
  • Das ist falsch: if(int(request.find("register"))!=std::string::npos). npos ist ein size_t, eine vorzeichenlose Ganzzahl, während int ist eine vorzeichenbehaftete Ganzzahl. Es gibt keine Notwendigkeit zu werfen das Ergebnis der find, und alles, was Sie tun, ist das hacken der Bereich in der Mitte. In der Tat, werden Sie immer geben diese if-Anweisung, da ein int wahrscheinlich niemals erreichen können, die maximale Wert einer size_t (was npos ist). Wenn es nicht der Fehler, es ist ein bug.
  • Ich würde vorschlagen, die Protokollierung der Länge von request und der Wert der bodypos. Das wird Ihnen mit Sicherheit sagen, ob Sie sehen, schlechte Verhalten von substr oder ob Sie bestanden in der schlechten Argumente.
  • Ich habe log die Länge und den Wert von request den Wert des bodypos. Aber es ist egal. Auch wenn ich den pass substr(2), es wird mir dieser Fehler. Die Länge der Zeichenfolge angemeldet ist immer um 150.
  • In Ergänzung zu meinem letzten Kommentar, das ist auch falsch: int bodypos = request.find("username"); Wieder, bist du hacken das Angebot in der Hälfte, und wird nie geben Sie die nachfolgende if-Anweisung. Ich denke, das sollte entstehen, eine Warnung; verwandeln Sie Ihren warn-levels zu sehen.
  • Ich verstehe, dass einige von Euch vielleicht Sache, ich habe eine vorgefasste Idee, dass der Fehler hier passiert, aber getestet habe ich diese alle über den Ort, einschließlich in einem anderen Programm. Nicht schätzen, einige der negativen Bemerkungen.
  • Ok, ich werde drehen Sie die Warnungen auf und versuchen mit size_t bodypos. Update: dasselbe.
  • Sollten Sie Ihren code anzupassen, dann, damit die Leute wissen, was Sie versucht haben, und dass der code verbessert wird.
  • Palatnik: Sie sollten nicht versuchen, "size_t bodypos". Sollten Sie verwenden std::string::size_type bodypos.
  • Ok werde ich verwenden, size_type. Gleiche Fehler.
  • Ich bin mir ziemlich sicher, dass std::string::size_type ist immer size_t. Es ist die Zuweisung der size_type, die die Standard-Zuweisung, wer ist size_type ist size_t.
  • Das einzige mal, dass ich gesehen habe, einen mysteriösen "bug" in einem string-Methode (oder in einem anderen Ort, wo nichts könnte möglicherweise falsch sein), es hatte zu tun mit nicht verwandten Undefiniertes Verhalten an anderer Stelle im Programm.
  • Durch die Art und Weise, die \r\n ist ein Ablenkungsmanöver, wenn Sie denken, dass es komprimiert \n - nur für I/O (und nur unter bestimmten Umständen auf einigen Plattformen, wenn Sie öffnen Sie die Dateien im text-Modus, auf einem neuen Mond, etc.).
  • Ich bin mir nicht sicher, warum Menschen downvote diese Frage. Es ist legitim code mit einem legitimen problem, lassen Sie uns helfen, den Kerl zu finden und zu bereinigen, unsere Antworten, so dass Sie anderen helfen, die vielleicht ähnliche Probleme.

InformationsquelleAutor stan | 2010-02-13
Schreibe einen Kommentar