2012-02-18 4 views
0

C++에서 ifstream을 사용하여 큰 파일 (~ 5GB)을 읽으려고합니다. 64 비트 OS를 사용하고 있기 때문에 문제가 아닌 것으로 생각했습니다. 아직도, 나는 segfault를 얻는다. 모든 것은 작은 파일 인 으로 잘 실행되므로 문제가있는 곳이 확실합니다.Segfault가 64 비트 ifstream으로 큰 파일을 읽는 중 데비안

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); 
} 

세그먼트 폴트는 = I에 대한 is.read 라인 187,664이다. 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

'희미한 빛 '이란 무엇입니까? 어떻게 할당 되나요? 당신은 그 끝을 지나고 있지 않다는 확신합니까? – 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 라이브러리입니다. 큰 파일 (실제로는> 2Go)을 사용하여 ifstream을 사용하는 방법을 찾지 못했습니다. 그 길을 찾았 니?

추신 : 귀하의 경우 size_t은 괜찮지 만, 32 비트 소프트웨어에서는 괜찮은지 잘 모르겠습니다. 나는 그것이 64 비트에서 괜찮다고 확신한다.

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

솔루션은 주석 중 하나입니다. –

관련 문제