Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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
C++ 为什么zlib deflateInit一次打电话就没用了?_C++_Zlib - Fatal编程技术网

C++ 为什么zlib deflateInit一次打电话就没用了?

C++ 为什么zlib deflateInit一次打电话就没用了?,c++,zlib,C++,Zlib,我目前正在编写一个函数,它使用zlib压缩字符数组。因为我想优化性能和速度,所以我只想调用deflateInit()一次,并重用zstream对象,因为我想避免重复重新分配、取消分配。我尝试了下面的方法,它只更新zstream对象中的输入和输出缓冲区,但它并没有从while循环的第二次迭代中给出正确的输出。代码如下: #include <stdio.h> #include <iostream> #include <string.h> // for strl

我目前正在编写一个函数,它使用zlib压缩字符数组。因为我想优化性能和速度,所以我只想调用deflateInit()一次,并重用zstream对象,因为我想避免重复重新分配、取消分配。我尝试了下面的方法,它只更新zstream对象中的输入和输出缓冲区,但它并没有从while循环的第二次迭代中给出正确的输出。代码如下:

#include <stdio.h>

#include <iostream>

#include <string.h> // for strlen

#include <assert.h>

#include <chrono>

#include "zlib.h"

// adapted from: http://stackoverflow.com/questions/7540259/deflate-and-inflate-zlib-h-in-c
int main(int argc, char * argv[]) {
  // original string len = 36
  char a[500] = {};

  for (int i = 0; i < 498; i++) {
    a[i] = 'a';
  }
  a[499] = '\0';

  // placeholder for the compressed (deflated) version of "a"
  char b[500] = {};

  // placeholder for the UNcompressed (inflated) version of "b"
  char c[500] = {};

  printf("Uncompressed size is: %lu\n", strlen(a));
  printf("Uncompressed string is: %s\n", a);

  printf("\n----------\n\n");

  z_stream defstream;
  defstream.zalloc = Z_NULL;
  defstream.zfree = Z_NULL;
  defstream.opaque = Z_NULL;
  deflateInit( & defstream, Z_BEST_COMPRESSION);

  int i = 0;
  while (i < 5) {

    auto t1 = std::chrono::high_resolution_clock::now();

    // setup "a" as the input and "b" as the compressed output

    // STEP 1.
    // deflate a into b. (that is, compress a into b)

    // zlib struct
    int ret;
    char b[500] = {};

    defstream.avail_in = (uInt) strlen(a) + 1; // size of input, string + terminator
    defstream.next_in = (Bytef * ) a; // input char array
    defstream.avail_out = 500;

    defstream.next_out = (Bytef * ) b;
    ret = deflate( & defstream, Z_FINISH); /* no bad return value */
    std::cout << "ret" << ret << std::endl;
    std::cout << "avail_out" << defstream.avail_out << std::endl;

    assert(ret != Z_STREAM_ERROR); /* state not clobbered */

    // This is one way of getting the size of the output
    printf("Compressed size is: %lu\n", strlen(b));
    printf("Compressed string is: %s\n", b);
    std::cout << "Compressed return value is: " << ret << std::endl;
    std::cout << "Avail out is: " << defstream.avail_out << std::endl;
    std::cout << "Compressed length is: " << defstream.total_out << std::endl;

    printf("\n----------\n\n");
    memset(b, 0, 500);


    auto t2 = std::chrono::high_resolution_clock::now();

    std::cout << "Timestamp: Total compression took: " <<
      std::chrono::duration_cast < std::chrono::microseconds > (t2 - t1).count() <<
      " microseconds\n";

    i++;
  }
  deflateEnd( & defstream);

  // inflateEnd(&infstream);

  return 0;
}
在这里您可以看到,我从while循环的第二次迭代中得到了错误代码-5(Z_BUF_error)和空b数组。但如果我在while循环中移动zlib对象声明和deflateInit(),一切都会正常工作。有什么解释吗?

在他们写的文件中:

如果参数flush设置为Z_FINISH,则处理挂起的输入,刷新挂起的输出,如果有足够的输出空间,则使用Z_STREAM_END deflate返回。如果deflate返回Z_OK或Z_BUF_ERROR,则必须使用Z_FINISH和更多输出空间(更新的avail_out)再次调用此函数,但不使用更多输入数据,直到它返回Z_STREAM_END或错误。deflate返回Z_STREAM_END后,流上唯一可能的操作是deflateReset或deflateEnd


所以它需要更多的缓冲区,注意你有一个500的缓冲区,但只说avail是50,这可能是错误,否则你需要更多的逻辑来添加更多的缓冲区。

但是如果我的输入缓冲区大小是500,那么理想情况下压缩不需要超过500,对吗?否则,如果需要更大的尺寸,压缩有什么用?
----------

ret1
avail_out35
Compressed size is: 9
Compressed string is: x�KL#
                           0
Compressed return value is: 1
Avail out is: 35
Compressed length is: 15

----------

Timestamp: Total compression took: 103 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is: 
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15

----------

Timestamp: Total compression took: 42 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is: 
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15

----------

Timestamp: Total compression took: 41 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is: 
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15

----------

Timestamp: Total compression took: 41 microseconds
ret-5
avail_out50
Compressed size is: 0
Compressed string is: 
Compressed return value is: -5
Avail out is: 50
Compressed length is: 15

----------

Timestamp: Total compression took: 42 microseconds