2

off_tto malloc()(where expect )の値を渡す際に問題が発生することはありsize_tますか?

ファイルを読み込んで、その内容をメモリに保存しています。ファイル サイズは、関数に渡された後にst_sizeメンバによって取得され、返されたメモリを my asとファイル サイズ asとして渡すための呼び出しを行う場所に渡されます。struct statstat()malloc()fread()malloc()bufnmemb

しかし、問題は、ファイル サイズが実際には 32 ビット/64 ビット マシンsize_tでの関数の動作によって保持できない大きな数値である場合: 整数オーバーフローと壊れた buf (要求されたバイト数ではなく) です。malloc()本当に戻ってきた)またはNULL

私はそれが本当に起こらないかもしれないことを知っているので、おそらく誰かがこのアプリケーションをスーパーコンピュータなどに使用し、私のパーサーに最大のファイルを要求します. .

4

2 に答える 2

1

ファイルサイズはどのくらいになると思いますか?中程度から大きなファイル(たとえば、数MiB、ただし2 GiB未満)の場合、問題は発生しません。ファイルが2GiBより大きく、32ビットシステムを使用している場合は、あらゆる種類の問題が発生します。ファイルが2GiBより大きいが、64ビット(Unix)マシンを使用している場合、問題は主に利用可能な物理メモリにあります(スラッシングを回避するため)。関係なく使用することを検討してくださいmmap()

しかし、問題は、ファイルサイズが実際にsize_tで保持できない大きな数値である場合、32ビット/ 64ビットマシンでのmalloc()関数の動作はどうなるかということです。

の値off_tが保持できる範囲よりも大きい場合size_t(32ビットシステムでは完全に妥当、Windows 64以外の64ビットシステムでは妥当ではない)、malloc()「機能」しますが、必要なスペースが割り当てられます。値の下位ビットoff_t。これはあなたが意図したものではありません。具体的ですがもっともらしい例として:off_tが64ビット量でsize_tあるが32ビット量である場合、の下位ビットは、上位ビットを無視して、off_tによってサイズとして使用されます。malloc()上位ビットがすべてゼロの場合、それは問題ではありません。上位ビットのいずれかが設定されている場合は、割り当てられていないメモリを悪用することになります。

malloc()問題を検出するためにできることは何もないことに注意してください。の宣言はそれが正しいタイプであると言っているsize_tので、コンパイラによって与えられます。<stdlib.h>コンパイラが切り捨てを警告するかどうかがすべてです。起こりうる問題について警告する義務はありません。

大きなファイルサイズでは、使用しているタイプの制限に注意する必要があります。また、期待する結果が得られるように細心の注意を払う必要があります(要求した結果だけでなく、そうではありません)。必然的に同じこと)。

于 2012-11-18T17:03:04.663 に答える
1

はい、問題が発生します。最初にファイルサイズを読み取ろうとすることで、ユーザーがパイプなどを使用することを本質的に禁止しているという事実から始めます。ファイル内のデータへのランダムアクセスが絶対に必要ですか? そうでない場合は、ストリーム指向の方法でファイルを解析してみてください。メモリ内で絶対に必要な場合はstat、ファイルサイズが収容できるサイズよりも大きいかどうかを最初に検証するために使用できます (ファイルサイズが構造体に収まらない場合は失敗することにoff_t注意してください)。または)、そうであれば早期に救済します (何らかの方法で RAM に読み込んだとしても、プロセスはポインターにアドレス指定するのに十分なビットを持っていないでしょう)、そうでない場合は試してくださいstaterrno==EOVERFLOWstatsize_tst_sizeSIZE_MAX((size_t)-1)malloc(そして戻り値をチェックしNULLます)または、おそらくmmap(利用可能な場合)あなたのファイル。


ポストスクリプトム

stat64@R は、それが非標準 (つまり、非 POSIX) であるため、私が言及することを好みませんでした。技術的には非常に正しいですが、実際stat64には、Linux、Solaris、OSX、HP-UX、AIX、QNX ですぐに利用できます (文書化されています)。 、さらには Windows の MSVCRT でも。OpenBSD では、regularはすでに大きなファイルをサポートしているため、OpenBSDでは使用できません。stat

2GB を超えるファイル サイズを取得する従来の (そしてやや標準的な_LARGEFILE_SOURCE) 方法は、 、 、_LARGEFILE64_SOURCEおよび_FILE_OFFSET_BITS=64を使用してビルドすることです。statstat64sizeof(off_t) >= 64/8

問題の真実は、あなたの場合、上記のすべてが学術的であるということです. 最初のチェックで正確なファイル サイズを知る必要はありません。ファイル サイズが と の小さい方のファイル サイズよりも大きい場合に限りoff_tますsize_t。それに応じて、元の回答トップを更新しました。

于 2012-11-18T17:05:52.260 に答える