读取二进制文件时的最大大小是多少?

时间:2015-09-03 15:57:25

标签: c binaryfiles

假设我想阅读双打数组。 然后我使用这段代码:

FILE *fp;
int n=100;
fp=fopen("file.bin","rb");
double *array=(double*)calloc(n,sizeof(double));
fread(array,sizeof(double),n,fp);
fclose(fp);

我可以安全地用于fread()功能的最大n是多少?

3 个答案:

答案 0 :(得分:3)

在你的代码中? MAX_INT,与平台有关。通常为2,147,483,647。但这并不能保证。

您受到真实硬件和机器状态的进一步限制。 malloc只能抓住可用的RAM。如果不存在,那就失败了。 如果您的机器中有256K的RAM,那就不多了。它远远低于256K。如果您拥有NSA的服务器和上帝自己的内存池......但是它充满了猫视频,malloc将会失败。< / p>

您可以进行一些实际分析,并确定在执行给定任务列表的给定系统上您可以释放多少内存。或者你可以把它保留在假定硬件的一小部分,并且希望它们不会用完。我认为重要的是要认识到你的内存分配可能会失败,并且程序需要优雅地失败。

这种不确定性是动态内存对于关键系统而言不可行的原因。

答案 1 :(得分:2)

答案在C标准7.19.8中提供。我将使用N1256草稿。

size_t fread(void * restrict ptr,
          size_t size, size_t nmemb,
          FILE * restrict stream);

由于[7.19.8.1]不提供任何限制,sizenmemb的值可以达到其类型提供的最大值 - SIZE_MAX [7.18.3.2],< em>只要 ptr指向的存储空间足够大。

您无法保证fread实际上会读取许多元素:

  

7.19.8.1.2 fread函数读入ptr指向的数组,最多 nmemb元素,其大小由{指定{1}} [...]如果读取了部分元素,则其值是不确定的。 (强调我的)

只要size可以分配它,您就可以用malloc填充它,尽管fread可以自由地读取较少数量的元素。例如,符合fread的实现可以合理地限制为一次性读取fread个元素。

因此,您使用min(SIZE_MAX/size, nmemb)是错误的。您必须继续阅读,直到您完成阅读需要阅读的内容,或发生错误,或者您已达到文件末尾。 Never test for feof prior to reading!

fread

答案 2 :(得分:1)

使用size_t n = SIZE_MAX 尝试分配最大的代码可以处理。

各种系统都有其他限制。

  1. 许多系统需要n*sizeof *array <= SIZE_MAX calloc()/fread()。因此,请使用n = SIZE_MAX/sizeof *array

  2. 可分配的内存可能超过实际内存calloc()不使用内存,只需分配它。即使fread()可能使用所有内存,因为文件输入很小。然而,依靠它并不是强有力的代码。

  3. 最后,一旦代码尝试使用其分配,就会发生内存不足的错误。

  4. 关于&#34;安全使用&#34;,代码应在NULL之后立即检查calloc()

    相反,建议阅读数据块,然后根据需要重新分配到一个大数组中。