zip_source_buffer 的 libzip 导致数据损坏 and/or 段错误

libzip with zip_source_buffer causes data corruption and/or segfaults

我正在尝试将 libzip 与 zip_source_buffer 结合使用,以将数据从本地缓冲区写入压缩文件。

std::vector<uchar> buf;
struct zip * z = zip_open(zipfilename.c_str(),ZIP_CREATE | ZIP_EXCL,NULL);
if (!z) {
    messagelabel->setText("failed to open zip file "+QString::fromStdString(zipfilename));
    return "";
}
//messagelabel->setText(QString::fromStdString(zipfilename));
//messagelabel->setText(QString::number(ulong(z)));
int errors = 0;
for (int i=0;i<16;i++) {
    imencode(format, frame[i],buf);
    struct zip_source *s;
    s = zip_source_buffer(z,buf.data(),buf.size(),0);
    std::string nameinzip = ("band"+to_string(i)+format);
    if (zip_add(z,nameinzip.c_str(),s) < 0) {
            messagelabel->setText("failed to add "+QString::fromStdString(nameinzip)+" to zip file");
            errors++;
            break;
    }
}
if (errors == 0) {
    struct zip_source *s;
    std::string caltext = caltotext(calfile);
    cout << caltext;
    s = zip_source_buffer(z,caltext.data(),caltext.size(),0);
    std::string nameinzip = "calinfo.csv";
    if (zip_add(z,nameinzip.c_str(),s) < 0) {
            messagelabel->setText("failed to add "+QString::fromStdString(nameinzip)+" to zip file");
            errors++;
    }
}
if (zip_close(z) < 0) {
    messagelabel->setText("failed to close zip file "+QString::fromStdString(zipfilename));
    errors++;
}

不幸的是,我在我的 zip 文件中发现了损坏的数据,并且在尝试调试结果时我的程序在明显不相关的代码(之前有效)中出现了段错误。

然后我在 valgrind 中尝试 运行 我的程序并从 zip_close 得到内存错误。我做错了什么?

似乎 libzip 文档具有误导性,zip_add 实际上并没有从源中读取数据并将其放入 zip,它只是将其排队放入 zip。所以每个缓冲区必须是独立的,你必须确保它的生命周期将持续到 zip 关闭之后。

在这种情况下,这意味着将 buf 从单个 std::vector 更改为 std::vector 的数组(每个图像一个)并将 caltext 的声明移到更高的范围。

不相关代码中的段错误原来是一个不相关的错误(数组太小)。