2012-02-18 18 views
0

C++でifstreamを使って大きなファイル(〜5GB)を読み込もうとしています。 私は64ビットOSなので、これは問題ではないと思っていました。 まだ、私はsegfaultを取得します。小さなファイルではすべてがうまく動作します。 だから問題はどこにあるのでしょうか。Segfaultが64ビット版のifstreamで大容量ファイルを読むDebian

私はg ++(4.4.5-8)とlibstdC++ 6(4.4.5-8)を使用しています。

ありがとうございました。

コードは次のようになります。

void load (const std::string &path, int _dim, int skip = 0, int gap = 0) { 
    std::ifstream is(path.c_str(), std::ios::binary); 
    BOOST_VERIFY(is); 
    is.seekg(0, std::ios::end); 
    size_t size = is.tellg(); 
    size -= skip; 
    long int line = sizeof(float) * _dim + gap; 
    BOOST_VERIFY(size % line == 0); 
    long int _N = size/line; 
    reset(_dim, _N); 
    is.seekg(skip, std::ios::beg); 
    char *off = dims; 
    for (long int i = 0; i < N; ++i) { 
     is.read(off, sizeof(T) * dim); 
     is.seekg(gap, std::ios::cur); 
     off += stride; 
    } 
    BOOST_VERIFY(is); 
} 

セグメンテーション違反は=私のためにis.readラインで187664です。 Tはfloatであり、一度にdim = 1000浮動小数点数を読み取っています。 segfaultが発生すると、i * strideはサイズよりも小さいので、ファイルの最後を過ぎて実行していません。

暗くは

void reset (int _dim, int _N) 
{ 
    BOOST_ASSERT((ALIGN % sizeof(T)) == 0); 
    dim = _dim; 
    N = _N; 
    stride = dim * sizeof(T) + ALIGN - 1; 
    stride = stride/ALIGN * ALIGN; 
    if (dims != NULL) delete[] dims; 
    dims = (char *)memalign(ALIGN, N * stride); 
    std::fill(dims, dims + N * stride, 0); 
} 
+1

どのようにファイルを読み取っていますか、セグメント違反はどこですか? –

+1

関連するコードを投稿してください。 – Joe

+0

'dims 'とは何ですか?どのように割り当てられていますか?あなたは終わりを過ぎて走っていないと確信していますか? – Mat

答えて

1

ここに割り当てられ、これはバグであるかどうかは知りませんが、このコードは非常に好きで、漏れるする機会がたくさんCに見えます。どのような方法は、あなたが常にsize_t型を使用したメモリで何かのサイズやインデックスを扱っているとき、オブジェクトの最大サイズを保持できることが保証されて

void reset (size_t dim, size_t _N) 
//I would avoid using leading underscores that is usually used to identify elements of the standard library. 

void reset (int _dim, int _N) 

を変更してみてくださいアレイを含む。

+0

ありがとうございます、あなたはもちろんです。しかし、これは問題ではありませんでした。 –

+0

@AndreasMuellerああ、別のクイック・ポイント、あなたはmemalignがそのような金額を提供できると確信していますか?あなたはそれを試してみましたか? (それは私がそれを多く割り当てることができない場合、std :: bad_allocをスローします)。また、このデータは構造化されているかフラットなファイルなので、read()の使い方は、型のコンテナを作成してエントリを埋め込むのではなく、ちょっと古い方法です。 – 111111

0

私はあなたのファイルの正しいサイズを持っている... _ftelli64などを使用し、それを管理するためにlong long(または_int64)変数を使用することがあると思います。しかし、それはCライブラリです。私はifstreamをとても大きなファイル(実際には> 2Go)で使用する方法を見つけることはできません。方法を見つけましたか?

PS:あなたのケースでは、size_tは問題ありませんが、32ビットソフトウェアでは問題ありません。私はそれが64ビットでOKだと確信しています。

int main() 
{ 
    string name="tstFile.bin"; 
    FILE *inFile,*inFile2; 
    fopen_s(&inFile,name.c_str(),"rb"); 
    if (!inFile) 
    { 
     cout<<"\r\n***error -> File not found\r\n"; 
     return 0; 
    } 

    _fseeki64 (inFile,0L,SEEK_END); 
    long long fileLength = _ftelli64(inFile); 
    _fseeki64 (inFile,0L,SEEK_SET); 

    cout<<"file lg : "<<fileLength<<endl; 
    return 1; 
} 
+0

解決策はコメントの1つにあります。 –

関連する問題