如果保存数据,libz 压缩将失败

libz compress fails if saving data

本文关键字:压缩 失败 libz 保存 数据 如果      更新时间:2023-10-16

我刚刚遇到了一个很奇怪的libz行为。如果我只使用压缩功能,一切正常,但如果我尝试例如。将压缩数据保存到我得到Z_BUF_ERROR的文件。我做错了什么?

#include <iostream>
#include <fstream>
#include "zlib.h"
typedef unsigned char byte_t;
static int read_filesize(const char* filename) {
    int size = -1;
    std::ifstream file(filename);
    if (!file.is_open()) return size;
    file.seekg(0, std::ios::end);
    size = (int) file.tellg();
    file.close();
    return size;
}
static bool read_binary_file(const char* filename, byte_t* dst, const unsigned length) {
    std::ifstream file(filename, std::ios::binary);
    if (!file.is_open()) return false;
    file.read((char*) dst, length);
    file.close();
    return true;
}
static bool save_binary_file(const char* filename, const byte_t* src, const unsigned length) {
    std::ofstream file(filename, std::ios::binary);
    if (!file.is_open()) return false;
    file.write((const char*) src, length);
    file.close();
    return true;
}
int main(int args, char **argv) {
    int fileSize = read_filesize(argv[1]);
    byte_t fileData[fileSize];
    bool result = read_binary_file(argv[1], fileData, fileSize);
    unsigned compressedSize = compressBound(fileSize);
    byte_t compressed[compressedSize]; 
    int compressionResult = compress(compressed, (unsigned long*) &compressedSize, fileData, fileSize);
    switch (compressionResult) {
    case Z_OK:
        std::cout << "Compression succeeded!n";
        break;
    case Z_MEM_ERROR:
        std::cout << "Error: Z_MEM_ERROR!n";
        return 1;
    case Z_BUF_ERROR:
        std::cout << "Error: Z_BUF_ERROR!n";
        return 1;
    default:
        std::cout << "Error: UNDEFINED!n";
        return 1;
    }
    std::cout << "Size of '" << argv[1] << "': " << fileSize << "n"
            << "After: " << compressedSize << "n";
    bool saveResult = save_binary_file("file.bin.z", compressed, compressedSize);  // everything works if I remove this instruction
    return 0;
}

从上面的评论来看,您使用的是 64 位架构,其中 sizeof(unsigned long)==8 ,而sizeof(unsigned)==4 .

因此,compressedSize属于unsigned型的投(unsigned long*)&compressedSize会产生未定义的行为。

只需将compressedSize声明更改为键入 unsigned long 即可解决此问题。

堆栈溢出?我不知道动态数组是如何在 g++ 中实现的,但如果将它们放在堆栈上,您可能会遇到大文件的问题。使用 std::vectorstd::array

int fileSize = read_filesize(argv[1]);
byte_t fileData[fileSize];

它是一个VLA(可变长度数组)。不得使用。请改用 std::vector。同样的事情也适用于compressed