none
std::ifstreamで開けるファイルサイズの上限 RRS feed

  • 質問

  • std::ifstreamで開けるファイルサイズの上限は何Byteなのでしょうか?

    size_tで表せる範囲ではないのでしょうか?

     

    下記のコードで377GByteのファイルを開くと、3回目のreadでアクセス違反になります。

    (x64、releaseの場合、debugの場合は2G読み込んだ時点では落ちてません)

     

    std::ifstream insList(argv[1], std::ios::binary);

    /* 中略 */

     

     unsigned long uBuf[2];
     char* pcBuf = reinterpret_cast<char*>(uBuf);
     for (size_t n = 0; insList.read(pcBuf, sizeof(long)*2); /* 空 */)
     {
    /* 中略 */

     }

     

    デバッガで調べると、basic_istream::_Read_sの

    const sentry _Ok(*this, true);

    の箇所で落ちているようですが、この sentry  クラスは何をしているのでしょうか?

     

    2008年6月30日 1:15

回答

  •  KanPro さんからの引用
    std::ifstreamで開けるファイルサイズの上限は何Byteなのでしょうか?

    size_tで表せる範囲ではないのでしょうか?


    特に決まっていないと思います。

    ifstream の場合は size_t よりは std:: streamsize の方が関係が深そうですが、

    こちらは一回で読み書きできるサイズ(および stream buffer)の上限を意味していて、

    ファイルのサイズではありません。


     KanPro さんからの引用
    下記のコードで377GByteのファイルを開くと、3回目のreadでアクセス違反になります。


    (2G で落ちないという部分との関連が良く分かりませんが、)

    3回目の read ということは、まだ sizeof(long) * 6 バイトしか読み込んでいないということですよね?

    しかも、アクセス違反とは尋常ではありません。なんとなく中略の部分が怪しい気がします。


     KanPro さんからの引用
    デバッガで調べると、basic_istream::_Read_sの

    const sentry _Ok(*this, true);

    の箇所で落ちているようですが、この sentry  クラスは何をしているのでしょうか?


    sentry は一般的に番兵と訳されます。

    番兵というと vector::end っぽいイメージがありますので、この場合の sentry は門番といったところでしょうか。

    sentry のコードをざっくり見た限りでは、スレッド関連のロックと、stream の状態チェック、

    スペースのスキップなどを担当しているようです。


    const sentry _Ok(*this, true); で落ちているとのことですが、

    もう少し具体的なところまで調べてみてはいかがでしょうか。

    コンストラクタの中まで潜っていって、実際にアクセス違反が発生している箇所をつきとめれば、

    本当に sentry が犯人なのかどうかが分かると思います。


    2008年6月30日 3:34

すべての返信

  •  KanPro さんからの引用
    std::ifstreamで開けるファイルサイズの上限は何Byteなのでしょうか?

    size_tで表せる範囲ではないのでしょうか?


    特に決まっていないと思います。

    ifstream の場合は size_t よりは std:: streamsize の方が関係が深そうですが、

    こちらは一回で読み書きできるサイズ(および stream buffer)の上限を意味していて、

    ファイルのサイズではありません。


     KanPro さんからの引用
    下記のコードで377GByteのファイルを開くと、3回目のreadでアクセス違反になります。


    (2G で落ちないという部分との関連が良く分かりませんが、)

    3回目の read ということは、まだ sizeof(long) * 6 バイトしか読み込んでいないということですよね?

    しかも、アクセス違反とは尋常ではありません。なんとなく中略の部分が怪しい気がします。


     KanPro さんからの引用
    デバッガで調べると、basic_istream::_Read_sの

    const sentry _Ok(*this, true);

    の箇所で落ちているようですが、この sentry  クラスは何をしているのでしょうか?


    sentry は一般的に番兵と訳されます。

    番兵というと vector::end っぽいイメージがありますので、この場合の sentry は門番といったところでしょうか。

    sentry のコードをざっくり見た限りでは、スレッド関連のロックと、stream の状態チェック、

    スペースのスキップなどを担当しているようです。


    const sentry _Ok(*this, true); で落ちているとのことですが、

    もう少し具体的なところまで調べてみてはいかがでしょうか。

    コンストラクタの中まで潜っていって、実際にアクセス違反が発生している箇所をつきとめれば、

    本当に sentry が犯人なのかどうかが分かると思います。


    2008年6月30日 3:34
  •  

    > なんとなく中略の部分が怪しい気がします。

     

    申し訳ありません。その通りでした。

    配列の添え字ミスでrdbufの値が書き換わっていました。(debug版では露呈せず)

     

    中略の部分があまりに単純なので、ここにミスがあるとは思いもよりませんでした。

    どうもありがとうございました。(お騒がせして申し訳ありません)

    2008年6月30日 5:12
  • こんにちは。中川俊輔 です。

     

    zakioさん、回答ありがとうございます。

     

    KanProさん、フォーラムのご利用ありがとうございます。

    有用な情報と思われたため、zakioさんの回答へ回答済みチェックをつけさせていただきました。

     

    回答済みチェックが付くことにより、有用な情報を探している方が情報を見つけやすくなります。
    有用な情報と思われる回答があった場合は、なるべく回答済みボタンを押してチェックを付けてください。

    KanProさんはチェックを解除することもできますので、ご確認ください。

     

    それでは!

    2008年7月14日 8:20