Domanda

Ho fatto una funzione come questa:

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

Il problema è che a volte, per errore, vengono passati argomenti che non sono stringhe (il che significa che p1 o p2 non termina con un carattere null). Quindi, strcmp continua il confronto fino a quando non raggiunge la memoria non accessibile e si arresta in modo anomalo. Esiste una versione sicura di strcmp ? Oppure posso dire se p1 (e p2 ) è una stringa o no in modo sicuro?

È stato utile?

Soluzione

No, non esiste un modo (standard) per stabilire se un char * indica effettivamente una memoria valida.

Nella tua situazione, è meglio usare std :: string piuttosto che char * s per tutte le tue stringhe, insieme al == operatore. In tal caso, il compilatore applica la sicurezza del tipo.

MODIFICA: Secondo i commenti seguenti se ti trovi in ??una situazione in cui a volte passi char * che possono essere o meno stringhe valide per funzioni che si aspettano stringhe con terminazione null quindi qualcosa di fondamentalmente sbagliato nel tuo approccio, quindi sostanzialmente @ la risposta di janm qui sotto.

Altri suggerimenti

In alcuni casi std :: strncmp può risolvere il tuo problema:

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

Confronta fino a num caratteri della stringa C str1 con quelli della stringa C str2.


Inoltre, dai un'occhiata a ciò che la US DHS National Cyber ??Security Division raccomanda su questo argomento:

  

Assicurati che le stringhe siano nulle prima di passare a strcmp. Questo può essere applicato posizionando sempre un \ 0 nell'ultimo byte allocato del buffer.

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 */ }

Se stai passando stringhe a strcmp () che non sono nulle, hai già perso. Il fatto che tu abbia una stringa che non è terminata con null (ma dovrebbe essere) indica che hai problemi più profondi nel tuo codice. Non puoi cambiare strcmp () per affrontare in modo sicuro questo problema.

Dovresti scrivere il tuo codice in modo che ciò non possa mai accadere. Inizia utilizzando la classe di stringhe. Ai limiti in cui prendi i dati nel tuo codice devi assicurarti di affrontare casi eccezionali; se ricevi troppi dati devi fare la cosa giusta. Ciò non comporta l'esecuzione alla fine del buffer. Se è necessario eseguire l'I / O in un buffer in stile C, utilizzare le funzioni in cui si specifica la lunghezza del buffer e si rilevano e si gestiscono i casi in cui il buffer non è abbastanza grande in quel punto.

Non c'è cura per questo che è portatile. La convenzione afferma che esiste un carattere aggiuntivo che contiene un carattere null che appartiene allo stesso blocco di memoria allocato correttamente della stringa stessa. O viene seguita questa convenzione e si verifica tutto il comportamento eccellente o indefinito.

Se conosci la lunghezza della stringa che confronti con puoi usare strncmp () ma il suo non aiuterà se la stringa passata al tuo codice è effettivamente più corta della stringa con cui confronti. / p>

puoi usare strncmp, ma se possibile usa std :: string per evitare molti problemi :)

Puoi mettere un limite massimo al numero di caratteri da confrontare usando strncmp .

Non esiste una risposta migliore a questa poiché non è possibile verificare che il carattere * sia una stringa. L'unica soluzione è quella di creare un tipo e usarlo per la stringa, ad esempio str :: string o crearne uno tuo se vuoi qualcosa di più leggero. vale a dire

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 ) {}

Non scrivi quale piattaforma stai usando. Windows ha le seguenti funzioni:

IsBadStringPtr potrebbe essere quello che stai cercando, se stai utilizzando Windows.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top