Frage

Ich habe eine Funktion wie diese:

bool IsSameString(char* p1, char* p2) 
{
     return 0 == strcmp(p1, p2);
}

Das problem ist, dass manchmal, die durch Fehler, Argumente übergeben werden, die keine Zeichenfolgen (was bedeutet, dass p1 oder p2 ist nicht beendet mit einem null-Zeichen).Dann, strcmp weiterhin vergleichen, bis es erreicht nicht-zugänglichen Speicher und stürzt ab.Gibt es eine sichere version von strcmp?Oder kann ich feststellen, ob p1 (und p2) ein string ist oder nicht auf sichere Art und Weise?

War es hilfreich?

Lösung

Nein, es gibt keine (Standard) Art und Weise zu sagen, ob ein char * Punkt tatsächlich auf gültige Speicher.

In Ihrer Situation ist es besser, std::string zu verwenden, anstatt char *s für alle Strings, zusammen mit den überlasteten == Betreibern. Wenn Sie dies tun, würde der Compiler Typsicherheit erzwingen.

EDIT: Gemäß den Kommentaren unten, wenn Sie sich in einer Situation, wo man manchmal char *s passieren, die keine gültigen Strings Funktionen sein können, die nullterminierten Strings erwarten dann ist etwas grundlegend falsch mit Ihrem Ansatz, so dass im Grunde @ Janm Antwort unten.

Andere Tipps

In einigen Fällen std::strncmp kann Ihr problem lösen:

int strncmp ( const char * str1, const char * str2, size_t num ); 

Es vergleicht bis zu num Zeichen der C-string str1, zu denen der C-string str2.


Werfen Sie auch einen Blick, was die US-DHS National Cyber Security Division empfiehlt auf dieser Angelegenheit:

Sicherstellen, dass die strings sind null-terminierte vor der übergabe in strcmp.Dies kann durchgesetzt werden, indem Sie immer die Platzierung einer \0 in den letzten reserviert byte des Puffers.

char str1[] ="something";
char str2[] = "another thing";
/* In this case we know strings are null terminated. Pretend we don't. */
str1[sizeof(str1)-1] = '\0';
str2[sizeof(str2)-1] = '\0';
/* Now the following is safe. */
if (strcmp(str1, str2)) { /* do something */ } else { /* do something else */ }

Wenn Sie Strings sind vorbei zu strcmp (), die nicht beendet sind null Sie haben schon verloren. Die Tatsache, dass Sie eine Zeichenfolge, die nicht null beendet wird (aber sein sollte) zeigt an, dass Sie tiefer Probleme in Ihrem Code. Sie können nicht strcmp () ändern, um sicher mit diesem Problem zu befassen.

Sie sollten Ihren Code schreiben, damit kann nie passieren. Beginnen Sie mit der String-Klasse. An den Grenzen, wo man Daten in den Code nehmen Sie müssen sicherstellen, dass Sie mit den Ausnahmefällen befassen; wenn Sie zu viel Daten erhalten müssen Sie das Richtige tun. Das beinhaltet nicht das Ende des Puffers wegzulaufen. Wenn Sie I / O in einen C-Stil-Puffer durchführen müssen, verwenden Sie Funktionen, wo Sie die Länge des Puffers definieren und erkennen und mit Fällen befassen, wo die Puffer an diesem Punkt nicht groß genug sind.

Es gibt keine Heilung für diese, die tragbar ist. Die Konvention besagt, dass es ein zusätzliches Zeichen ein Null-Zeichen hält, die sich auf den gleichen korrekt zugeordnet Speicherblock als Zeichenkette gehört. Entweder ist dieser Konvention folgt und alles ist in Ordnung oder nicht definiertes Verhalten auftritt.

Wenn Sie wissen, die Länge der Zeichenfolge, die Sie vergleichen gegen Sie strncmp() verwenden können, aber sein wird nicht helfen, wenn die Zeichenfolge, um Ihren Code übergeben tatsächlich kürzer als die Zeichenfolge, die Sie vergleichen gegen.

Sie strncmp verwenden können, aber wenn möglich die Verwendung std :: string viele Probleme :)

zu vermeiden

Sie können eine Obergrenze für die Anzahl der Zeichen setzen die zu vergleichen mit strncmp Funktion.

Es gibt keine beste Antwort auf diese Frage, da Sie nicht die char * ist eine Zeichenfolge überprüfen können. Die einzige Lösung ist eine Art zu erstellen und es für String für str :: string Beispiel verwenden oder eigene erstellen, wenn Sie etwas leichter werden sollen. dh

struct MyString
  {
  MyString() : str(0), len(0) {}
  MyString( char* x ) { len = strlen(x); str = strdup(x); }
  ⁓MyString() { if(str) free(str); }
  char* str;
  size_t len;
  };

bool IsSameString(MyString& p1, MyString& p2) 
  {
  return 0 == strcmp(p1.str, p2.str);
  }


MyString str1("test");
MyString str2("test");

if( IsSameString( str1, str2 ) {}

Sie nicht schreiben, welche Plattform Sie verwenden. Windows verfügt über folgende Funktionen:

IsBadStringPtr könnte das sein, was Sie suchen, wenn Sie Windows verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top