4

強い型、この場合はcharはバッファオーバーフローを防ぎますか?

char a[100]
char b[100]

strcpy(a,unknownFunction); // unknownFunction could overflow b 
                           // since its length is unknown

strcpy(b,a); // can b still overflow a with its now, 
             // potentially overflowed size?
4

5 に答える 5

9

いいえ strcpy()。nullターミネータ('\0')が見つかるまで続行します。含まれていない場合b[]は、最終的に1つが見つかるまで、ランダムメモリをウォークスルーします。

于 2010-09-02T16:31:12.817 に答える
5

C には強い型システムがありません。

C++ はやや強力な型付けですが、実際には真の強力な型システムではありませんreinterpret_cast

型システムがバッファ オーバーフローを防止するには、型情報が (1) 任意の長さの文字列を示すか、(2) 型自体のバッファ長をエンコードする必要があります。さらに、型判定システムは、変換の buffer-length が以下であることを保証する必要があります。

編集:

ある程度の注意を払い、C++ のキャスト スタスティック機能を無視すると、C++ で「適度に強力な」オーバーフローのないバッファー クラスを作成できます。ただし、これは用語の一般的な定義に従って厳密に型指定されているわけではありません。これは、無効なポイントでバッファーにアクセスしようとしてもコンパイルが必要になる可能性があるためです。真のテンプレート タイプの SafeBuffer を作成できる私よりもはるかにテンプレートに優れた人がいます。

これが私のカットです:

template<int Length>
class SafeBuffer
{
    unsigned char[Length];
public:
    unsigned char& operator[](int index); //when implemented, throws exception on out-of-range access.
};

SafeBuffer<10> buf, foo;
SafeBuffer<9> bar;
buf = foo; //pass
buf = bar; //compile-time error.
buf[100]; //compiles, but generates error at runtime. 

のコンパイル エラーを強制するために、テンプレートの型判定システムを利用していることに注意してくださいbuf = bar。これは、厳密に型指定されたシステムでできることの例です (C++ では、キャストによって型指定が 100% 破壊される可能性があることにも注意してください)。

于 2010-09-02T16:49:49.877 に答える
3

の引数のタイプはstrcopy()ですchar *。これは、配列をに渡すとstrcpy()、これらが固定サイズの配列であることを知る方法がないことを意味します。関数に関する限り、それらは単なるポインタであり、で見つかるまで要素をコピーし続け\0ますb

重要な点は、関数がポインタである引数をとると、それが単一のオブジェクトへのポインタ、動的に割り当てられたバッファへのポインタ、またはスタックに割り当てられた固定サイズの配列であるかどうかを判断する方法がないということです。

したがって、答えは「いいえ」です。

于 2010-09-02T16:37:11.957 に答える
1

それでもオーバーフローする可能性がstrcpy stopsあります。オーバーフローを防ぐためにNULが見つかった場合は、strlcpyまたはを使用する必要があります。strncpy

// using strlcpy
strlcpy(a, unknownFunction, 100);

// using strncpy
strncpy(a, unknownFunction, 100); 
a[99] = 0; // strncpy doesn't NUL-terminate the result
于 2010-09-02T16:35:36.827 に答える
0

一般strncpyに、のより安全な代替手段strcpyです。

于 2010-09-02T16:34:24.927 に答える