Pergunta

Eu fiz uma função como esta:

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

O problema é que, às vezes, por engano, os argumentos são passados ??que não são strings (o que significa que p1 ou p2 não é encerrado com um caractere nulo). Então, strcmp continua comparando até atingir a memória e acidentes não acessível. Existe uma versão segura de strcmp? Ou posso dizer se p1 (e p2) é uma cadeia ou não de uma maneira segura?

Foi útil?

Solução

Não, não há nenhuma maneira (padrão) para dizer se um char * realmente aponta para memória válido.

Na sua situação, é melhor std::string uso ao invés de char *s para todas as suas cordas, juntamente com o operador == sobrecarregado. Se você fizer isso, o compilador iria reforçar a segurança de tipos.

EDIT: de acordo com os comentários abaixo se você se encontra em uma situação onde você às vezes passam char *s que podem ou não podem ser strings válidas para funções que esperam cadeias de terminação nula então algo está fundamentalmente errado com a sua abordagem, por isso, basicamente, @ Do JANM resposta abaixo.

Outras dicas

Em alguns casos std::strncmp pode resolver seu problema:

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

Ele compara-se a personagens NUM dos str1 C aos do str2 corda C.


Além disso, dê uma olhada, o que a Divisão National Cyber ??Security US DHS recomenda sobre este assunto:

Certifique-se de que as cordas são nulo terminada antes de passar para strcmp. Isso pode ser aplicada por sempre colocar um \ 0 no último byte alocado do 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 você estiver passando cordas para strcmp () que não estão nulos terminadas você já perdeu. O fato de que você tem uma seqüência que não tem um terminador nulo (mas deveria ser) indica que você tem questões mais profundas em seu código. Você não pode mudar strcmp () para lidar com segurança com este problema.

Você deve escrever seu código para que nunca pode acontecer. Comece usando a classe string. Nos limites em que você toma os dados em seu código, você precisa ter certeza de que você lidar com os casos excepcionais; se você receber muitos dados que você precisa para fazer a coisa certa. Que não envolve a correr no final do seu buffer. Se você deve executar I / O em um buffer de estilo C, use funções onde você especifica o tamanho do buffer e detectar e lidar com casos em que o buffer não é grande o suficiente nesse ponto.

Não há nenhuma cura para esta que é portátil. A convenção estabelece que há um caractere extra segurando um caractere nulo que pertence ao mesmo bloco corretamente alocados da memória como a própria corda. Ou esta convenção é seguido e está tudo bem ou comportamento indefinido ocorre.

Se você sabe o comprimento da corda que você comparar com você pode usar strncmp() mas sua vontade não ajuda se a string passada ao seu código é realmente menor do que a seqüência que você comparar contra.

Você pode usar strncmp, mas se possível usar std :: string para evitar muitos problemas :)

Você pode colocar um limite superior para o número de caracteres a ser comparada usando o strncmp função .

Não há melhor resposta para isso, como você não pode verificar a char * é uma string. A única solução é criar um tipo e usá-lo para cordas por exemplo str :: string ou criar seu próprio se você quiser algo mais leve. ie

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

Você não escrita, que plataforma você está usando. O Windows tem as seguintes funções:

IsBadStringPtr pode ser o que você está procurando, se você estiver usando o Windows.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top