문제
저는 다음과 같은 함수를 만들었습니다.
bool IsSameString(char* p1, char* p2)
{
return 0 == strcmp(p1, p2);
}
문제는 때때로 실수로 문자열이 아닌 인수가 전달된다는 것입니다(즉, p1
또는 p2
널 문자로 끝나지 않습니다).그 다음에, strcmp
액세스할 수 없는 메모리에 도달하여 충돌이 발생할 때까지 계속 비교합니다.안전한 버전이 있습니까? strcmp
?아니면 알 수 있을까요? p1
(그리고 p2
)은 문자열인가요, 안전한 방식이 아닌가요?
해결책
아니요, (표준) 방법이 없습니다. char *
실제로 유효한 메모리를 가리 킵니다.
귀하의 상황에서 사용하는 것이 좋습니다 std::string
보다는 char *
과부하와 함께 모든 문자열에 대한 s ==
운영자. 이렇게하면 컴파일러가 유형 안전을 시행합니다.
편집하다: 아래의 의견에 따라 가끔 통과하는 상황에 처한 경우 char *
null이 종결 된 문자열을 기대하는 함수에 대한 유효한 문자열 일 수도 있고 아닐 수도있는 s는 접근 방식에 근본적으로 문제가 있으므로 기본적으로 @Janm의 답변은 아래에 있습니다.
다른 팁
일부 경우에 std::strncmp
문제를 해결할 수 있습니다:
int strncmp ( const char * str1, const char * str2, size_t num );
C 문자열 str1의 최대 num 문자를 C 문자열 str2의 문자와 비교합니다.
또한 미국 DHS 국가 사이버 보안 부서(National Cyber Security Division)가 추천하다 이 문제에서는:
strcmp에 전달하기 전에 문자열이 null로 끝나는지 확인하세요.이는 항상 버퍼의 마지막 할당 바이트에 \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 ()를 변경할 수 없습니다.
결코 일어나지 않을 수 있도록 코드를 작성해야합니다. 문자열 클래스를 사용하여 시작하십시오. 코드에 데이터를 가져 오는 경계에서 예외적 인 사례를 처리해야합니다. 데이터가 너무 많으면 올바른 일을해야합니다. 버퍼의 끝을 달리는 것은 포함되지 않습니다. C 스타일 버퍼로 I/O를 수행 해야하는 경우 버퍼의 길이를 지정하고 해당 시점에서 버퍼가 충분히 크지 않은 경우를 감지하고 처리하는 기능을 사용하십시오.
휴대용 이에 대한 치료법은 없습니다. 컨벤션은 문자열 자체와 동일하게 할당 된 메모리 블록에 속하는 널 캐릭터를 소지 한 추가 캐릭터가 있다고 명시하고 있습니다. 이 협약이 따르고 모든 것이 괜찮거나 정의되지 않은 행동이 발생합니다.
당신이 비교할 수있는 줄의 길이를 알고 있다면 당신과 비교할 수 있습니다. 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를 사용하는 경우 찾고있는 것일 수 있습니다.