Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
zlib compress()返回Z_BUF_错误,尽管为compressBound的结果分配了缓冲区(文件太大?)_C_Compression_Zlib - Fatal编程技术网

zlib compress()返回Z_BUF_错误,尽管为compressBound的结果分配了缓冲区(文件太大?)

zlib compress()返回Z_BUF_错误,尽管为compressBound的结果分配了缓冲区(文件太大?),c,compression,zlib,C,Compression,Zlib,使用zlib时,尽管我认为缓冲区分配是正确的,但当我试图压缩13G的文件时,调用compress()会产生Z_BUF_错误。这段代码适用于较小的文件 struct stat infile_stat; FILE *fp = NULL; if ((fp = fopen(md_of_name, "r")) == NULL) { fprintf(stderr, "Error: Unable to open file %s.\n", md_of_name);

使用zlib时,尽管我认为缓冲区分配是正确的,但当我试图压缩13G的文件时,调用
compress()
会产生
Z_BUF_错误。这段代码适用于较小的文件

struct stat infile_stat;
FILE *fp = NULL;

if ((fp = fopen(md_of_name, "r")) == NULL) {
  fprintf(stderr,
          "Error: Unable to open file %s.\n",
          md_of_name);
  exit(1);
}

stat(md_of_name, &infile_stat);
size_t u_len = infile_stat.st_size;

char *u_buf = (char *)malloc(u_len);

if (u_buf == NULL) {
  fprintf(stderr, "Error: Unable to malloc enough memory for the "
                   "uncompressed buffer\n");
  exit(1);
}

if (fread(u_buf, 1, u_len, fp) < u_len) { // d
  fprintf(stderr,
          "Error: Unable to read in all of file %s. Exiting.\n ",
          md_of_name);
  exit(1);
}
fclose(fp);

size_t c_len = compressBound(u_len);

Bytef *c_buf = (Bytef *)malloc(c_len);

if (c_buf == NULL) {
  fprintf(stderr, "Error: Unable to malloc enough memory for the "
                  "compressed BIM buffer\n");
  exit(1);
}

fprintf(stderr, "u_len:%lu\tc_len:%lu\tc_buf:%p\n", u_len, c_len, c_buf);

int r = compress(c_buf, &c_len, (Bytef *)u_buf, u_len);

if (r == Z_MEM_ERROR)
  fprintf(stderr, "Not enough memory\n");
else if (r == Z_BUF_ERROR)
  fprintf(stderr, "Not enough room in the output buffer.\n");
assert(r == Z_OK);
然后是断言失败

更新

我相信这个错误是由于zlib中
compress()
函数内部的强制转换问题造成的。如果我是正确的,则在zlib 1.2.8的
compress.c
的第40行返回错误,这是

if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
stream.avail\u out
变量在上面几行设置为:

stream.avail_in = (uInt)sourceLen;
我认为演员阵容才是问题所在
sourceLen
是一个无符号长字符,当它被转换为
uInt时,位被丢弃。在我的例子中,
sourceLen
是13922075353,
destLen
是13926324460(from
compressBound()
),但由于cast
流的缘故。avail\u out
是1041422572。因此出现了错误


如果这是正确的,那么缓冲区的大小有一个隐式的界限。我现在不明白的是为什么缓冲区大小是无符号长的。它们需要是无符号整数。

现在我知道要查找什么了,我在中看到了这个问题的地址,其中指出
compress()
uncompress()
可能限制为4GB,因为它们在单个调用中运行。”


我仍然认为压缩和解压缩不应将大小作为无符号长。对于如此大的大小,需要使用
deflateInit()
deflate()
,和
deflateEnd()

通过将类型从无符号长更改为显式,在compress()参数中显式显示大小是否有用(这意味着一个非常大的最大值)转换为unsigned int?特别是因为这些long会立即转换为int?否。zlib的下一个版本不会转换为unsigned int。
stream.avail_in = (uInt)sourceLen;