2012-02-18 79 views
0

我想在C++中使用ifstream讀取大文件(〜5GB)。 由於我在64位操作系統上,我認爲這不應該是一個問題。 不過,我收到段錯誤。一切運行良好與小文件, 所以我敢肯定,這是問題所在。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線對於i = 187664。 T是浮點數,我一次讀dim = 1000浮點數。 當segfault發生時,i * stride小於size,所以我沒有跑過文件的末尾。

變暗這裏

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

你是如何讀取文件的,以及分段錯誤的確切位置? – 2012-02-18 14:29:59

+1

發佈一些相關的代碼。 – Joe 2012-02-18 14:32:13

+0

什麼是dims?如何分配?你確定你沒有跑過去嗎? – Mat 2012-02-18 14:40:49

回答

1

我不知道這是錯誤分配,但是這個代碼看起來非常像Ç和大量的機會泄漏。任何嘗試改變

void reset (int _dim, int _N) 

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. 

當您正在使用的大小或在內存大一些指數交易始終使用爲size_t,可以保證它能夠保持一個對象的最大尺寸包括數組。

+0

謝謝,你說得對,當然。雖然這不是問題。 – 2012-02-18 15:25:41

+0

@AndreasMueller哦,好吧,另一個快速點,你確定memalign是能夠提供這樣的數額?你有沒有嘗試過,但使用舊的新的? (如果我不能分配那麼多的話,會拋出一個std :: bad_alloc)。也是這個數據結構或只是一個平面文件,我問,因爲使用read()有點舊的方式作爲反對創建一個類型的容器和填充條目。 – 111111 2012-02-18 15:30:32

0

我認爲你必須使用_ftelli64 etc ...來確定文件的大小,並使用long long(或_int64)變量來管理它。但它是C庫。我沒有找到如何使用ifstream這麼大的文件(actualy> 2Go)。你找到了路嗎?

PS:在你的情況下,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

該解決方案在其中一個評論中。 – 2012-09-28 07:17:32