1

我刚刚遇到了一个非常奇怪的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;
}
4

3 回答 3

3

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

因此,(unsigned long*)&compressedSize类型compressedSize为 的类型unsigned转换会产生未定义的行为。

只需更改compressedSizeto type的声明即可unsigned long解决此问题。

于 2013-11-04T16:41:35.443 回答
0
int fileSize = read_filesize(argv[1]);
byte_t fileData[fileSize];

它是 VLA(可变长度数组)。不得使用它们。改用 std::vector 。同样适用于compressed

于 2013-11-04T11:40:40.220 回答
0

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

于 2013-11-01T12:50:34.650 回答