Pregunta

Hice una función como esta:

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

El problema es que a veces, por error, se pasan argumentos que no son cadenas (lo que significa que p1 o p2 no termina con un carácter nulo). Luego, strcmp continúa comparando hasta que alcanza la memoria no accesible y se bloquea. ¿Hay una versión segura de strcmp ? ¿O puedo saber si p1 (y p2 ) es una cadena o no de manera segura?

¿Fue útil?

Solución

No, no hay una manera (estándar) de saber si un char * en realidad apunta a una memoria válida.

En su situación, es mejor usar std :: string en lugar de char * s para todas sus cadenas, junto con el sobrecargado == operador. Si haces esto, el compilador impondrá seguridad de tipo.

EDITAR: según los comentarios a continuación si se encuentra en una situación en la que a veces pasa char * s que pueden o no ser cadenas válidas para funciones que esperan cadenas terminadas en nulo, entonces algo está fundamentalmente mal con su enfoque, así que básicamente La respuesta de @Janm a continuación.

Otros consejos

En algunos casos std :: strncmp puede resolver su problema:

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

Compara hasta varios caracteres de la cadena C str1 con los de la cadena C str2.


También, vea lo que hace la División Nacional de Seguridad Cibernética del DHS de los Estados Unidos recomienda sobre este asunto:

  

Asegúrese de que las cadenas terminen en nulo antes de pasar a strcmp. Esto se puede hacer siempre colocando un \ 0 en el último byte asignado del búfer.

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

Si está pasando cadenas a strcmp () que no están terminadas en nulo, ya ha perdido. El hecho de que tenga una cadena que no esté terminada en nulo (pero debería estarlo) indica que tiene problemas más profundos en su código. No puedes cambiar strcmp () para resolver este problema de forma segura.

Debes estar escribiendo tu código para que eso nunca pueda suceder. Comience utilizando la clase de cadena. En los límites en los que ingresa los datos en su código, debe asegurarse de tratar con los casos excepcionales; Si obtiene demasiados datos, debe hacer lo correcto. Eso no implica salir del final de tu búfer. Si debe realizar I / O en un búfer de estilo C, use funciones en las que especifique la longitud del búfer y detecte y resuelva los casos en que el búfer no sea lo suficientemente grande en ese momento.

No hay cura para esto que sea portátil. La convención establece que hay un carácter adicional que contiene un carácter nulo que pertenece al mismo bloque de memoria asignado correctamente como la propia cadena. O se sigue esta convención y se produce un comportamiento fino o indefinido de todo.

Si sabe la longitud de la cadena con la que se compara, puede usar strncmp () , pero esto no ayudará si la cadena que se pasa a su código es realmente más corta que la cadena con la que se compara.

puedes usar strncmp, pero si es posible usa std :: string para evitar muchos problemas :)

Puede poner un límite superior en el número de caracteres que se van a comparar utilizando el función strncmp .

No hay una mejor respuesta a esto, ya que no puedes verificar que char * es una cadena. La única solución es crear un tipo y usarlo para la cadena, por ejemplo, str :: string o crear el suyo propio si desea algo más ligero. es decir,

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

Usted no escribe, qué plataforma está utilizando. Windows tiene las siguientes funciones:

IsBadStringPtr puede ser lo que está buscando, si está usando Windows.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top