Вопрос

Я создал функцию, подобную этой:

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

Проблема в том, что иногда по ошибке передаются аргументы, которые не являются строками (это означает, что p1 или p2 не завершается нулевым символом).Затем, strcmp продолжает сравнение до тех пор, пока не достигнет недоступной памяти и не выйдет из строя.Существует ли безопасная версия strcmp?Или я могу сказать, действительно ли p1p2) является ли строка безопасным способом или нет?

Это было полезно?

Решение

Нет, не существует (стандартного) способа определить, является ли char * фактически указывает на действительную память.

В вашей ситуации лучше использовать std::string вместо того , чтобы char *s для всех ваших строк, вместе с перегруженным == оператор.Если вы сделаете это, компилятор обеспечит безопасность типов.

Редактировать: Согласно комментариям ниже, если вы окажетесь в ситуации, когда вы иногда проходите мимо char *s, которые могут быть или не быть допустимыми строками для функций, которые ожидают строки с нулевым завершением, тогда что-то в корне неправильно в вашем подходе, поэтому в основном ответ @janm ниже.

Другие советы

В некоторых случаях std::strncmp может решить вашу проблему:

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

Он сравнивает до num символов строки C str1 с символами строки C str2.


Кроме того, взгляните, что делает Национальный отдел кибербезопасности DHS США рекомендует по этому вопросу:

Убедитесь, что строки завершаются нулем перед передачей в strcmp.Это можно обеспечить, всегда помещая \0 в последний выделенный байт буфера.

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

Если вы передаете strcmp() строки, которые не завершаются нулем, вы уже проиграли.Тот факт, что у вас есть строка, которая не заканчивается нулем (но должна заканчиваться), указывает на то, что у вас есть более глубокие проблемы в вашем коде.Вы не можете изменить strcmp(), чтобы безопасно справиться с этой проблемой.

Вы должны писать свой код так, чтобы этого никогда не произошло.Начните с использования класса string.На границах, где вы вводите данные в свой код, вам нужно убедиться, что вы имеете дело с исключительными случаями;если вы получаете слишком много данных, вам нужно поступить правильно.Это не связано с запуском конца вашего буфера.Если вам необходимо выполнить ввод-вывод в буфер в стиле C, используйте функции, в которых вы указываете длину буфера, а также обнаруживаете и обрабатываете случаи, когда буфер на данный момент недостаточно велик.

От этого нет переносимого лекарства.Соглашение гласит, что существует дополнительный символ, содержащий нулевой символ, который принадлежит тому же правильно выделенному блоку памяти, что и сама строка.Либо это соглашение соблюдается, и все в порядке, либо происходит неопределенное поведение.

Если вы знаете длину строки, с которой вы сравниваете, вы можете использовать strncmp() но это не поможет, если строка, переданная в ваш код, на самом деле короче строки, с которой вы сравниваете.

вы можете использовать strncmp, но, если возможно, используйте std::string, чтобы избежать многих проблем :)

Вы можете установить верхний предел количества сравниваемых символов, используя strncmp функция.

Лучшего ответа на этот вопрос нет, поскольку вы не можете проверить, что char * является строкой.Единственное решение - создать тип и использовать его для string, например str::string, или создать свой собственный, если вы хотите что-то более легкое.т. е.

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

Вы не пишете, какую платформу вы используете.Windows обладает следующими функциями:

IsBadStringPtr возможно, это то, что вы ищете, если вы используете Windows.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top