質問
次のような関数を作りました。
bool IsSameString(char* p1, char* p2)
{
return 0 == strcmp(p1, p2);
}
問題は、時々誤って文字列ではない引数が渡されることです (つまり、 p1
または p2
ヌル文字で終了していません)。それから、 strcmp
アクセス不能なメモリに到達してクラッシュするまで比較を続けます。の安全なバージョンはありますか strcmp
?それとも、 p1
(そして p2
) は文字列であるかどうかは安全ですか?
解決
いいえ、 char *
が実際に有効なメモリを指しているかどうかを判断する(標準の)方法はありません。
あなたの状況では、オーバーロードされた == <とともに、すべての文字列に
char *
sではなく std :: string
を使用する方が良い/ code>演算子。これを行うと、コンパイラは型安全性を強制します。
編集:有効な文字列である場合とそうでない場合がある char *
を期待する関数に渡す場合がある場合は、以下のコメントのようにnullで終わる文字列を使用すると、アプローチが根本的に間違っているため、基本的に
以下の@janmの回答。
他のヒント
場合によっては std :: strncmp
は問題を解決できます:
int strncmp ( const char * str1, const char * str2, size_t num );
C文字列str1の最大num文字と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 */ }
nullで終了していない文字列をstrcmp()に渡す場合、すでに失われています。 nullで終端されていない(そうすべきである)文字列があるという事実は、コードにさらに深い問題があることを示しています。この問題に安全に対処するためにstrcmp()を変更することはできません。
決して起こらないようにコードを書くべきです。文字列クラスを使用して開始します。コードにデータを取り込む境界では、例外的なケースに対処する必要があります。データが多すぎる場合は、正しいことを行う必要があります。それはあなたのバッファの端から実行することを含みません。 Cスタイルのバッファーへの入出力を実行する必要がある場合は、バッファーの長さを指定する関数を使用し、その時点でバッファーが十分に大きくない場合を検出して処理します。
これには移植性のある治療法はありません。規則では、文字列自体と同じ正しく割り当てられたメモリのブロックに属するヌル文字を保持する余分な文字があると述べています。この規則に従うと、すべての正常な動作または未定義の動作が発生します。
比較する文字列の長さがわかっている場合は、 strncmp()
を使用できますが、コードに渡される文字列が実際に比較する文字列よりも短い場合は役に立ちません。
strncmpを使用できますが、可能であれば多くの問題を回避するためにstd :: stringを使用してください:)
char *が文字列であることを確認できないため、これに対する最善の答えはありません。唯一の解決策は、型を作成し、たとえば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 を使用している場合は、これが探しているものかもしれません。