在尝试使用fread
读取下一个字节之前,我试图跳过大量字节。
当尺寸很小#define size 6404168
时 - 它有效:
long int x = ((long int)size)*sizeof(int);
fseek(fincache, x, SEEK_CUR);
当大小很大#define size 649218227
时,它不会:(下一个fread
读取垃圾,无法真正理解它所读取的偏移量。
使用fread
作为解决方法在两种情况下均有效,但速度很慢:
temp = (int *) calloc(size, sizeof(int));
fread(temp,1, size*sizeof(int), fincache);
free(temp);
答案 0 :(得分:2)
假设sizoef(int)
为4
并且您使用的是32位系统(sizeof(long)为4),
所以649218227 * 4会溢出 long 所能容纳的内容。有符号整数溢出是未定义的行为。因此,它适用于较小的值(小于LONG_MAX)。
您可以使用循环代替fseek()
必需的字节。
long x;
intmax_t len = size;
for(;len>0;){
x = (long) (len>LONG_MAX?LONG_MAX:len);
fseek(fincache, x, SEEK_CUR);
len = len-x;
}
答案 1 :(得分:1)
offset
的{{1}}参数必须是fseek
,而不是long
。因此long long
必须符合x
,否则请勿使用long
。
答案 2 :(得分:1)
fseek的输入指南:
http://www.tutorialspoint.com/c_standard_library/c_function_fseek.htm
int fseek(FILE *stream, long int offset, int whence)
offset - 这是从哪里偏移的字节数。
您通过将long long
(其值大于Long int
的最大值)传递给fseek而不是所需的long
来调用未定义的行为。
众所周知,UB可以做任何事情,包括不工作。
答案 3 :(得分:1)
由于您的平台int
最有可能是32位,因此将649,218,227与sizeof(int)
相乘会产生超过INT_MAX
和LONG_MAX
的数字,这是在32位平台上都是2 ** 31-1。由于fseek
接受long int
,因此产生的溢出会导致程序打印垃圾。
您应该查阅编译器的文档,以确定它是否为64位搜索提供了扩展。例如,在POSIX系统上,您可以使用fseeko
,它接受off_t
类型的偏移量。
在调用64位搜索功能之前,请注意不要引入溢出。细致的代码可能如下所示:
off_t offset = (off_t) size * (off_t) sizeof(int);
fseeko(fincache, offset, SEEK_CUR);
答案 4 :(得分:0)
试试这个,如果数量如此之大,你可能需要阅读它
size_t toseek = 6404168;
//change the number to increase it
while(toseek>0)
{
char buffer[4096];
size_t toread = min(sizeof(buffer), toseek);
size_t read = fread(buffer, 1, toread, stdin);
toseek = toseek - read;
}