我试图在C ++中使用ifstream读取一个大文件(~5GB)。 由于我是64位操作系统,我认为这应该不是问题。 不过,我得到了一个段错误。一切都运行得很好,文件较小, 所以我很确定这就是问题所在。
我正在使用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 = 187664,段错误位于is.read
行。
T是浮动的,我一次读的是dim = 1000浮点数。
当发生段错误时,i *步幅小于大小,所以我没有超过文件的末尾。
dims在这里分配
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);
}
答案 0 :(得分:1)
我不知道这是不是错误,但是这段代码看起来非常像C并且有很多机会泄漏。任何方式尝试改变
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,它保证能够保持包括数组在内的对象的最大大小。
答案 1 :(得分:0)
我认为您必须使用_ftelli64
等...来获得正确的文件大小,并使用long long
(或_int64
)变量来管理它。但它是C库。我没有找到如何使用ifstream
这么大的文件(实际上&gt; 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;
}