我尝试创建一个压缩文件并使用两个库(pugixml / libzip)在其中插入xml文件,所有操作都没有错误,但是当我打开xml文件时,文件开头的编码很奇怪:
Main.cpp :
#include <iostream>
#include <sstream>
#include <zip.h>
#include <pugixml.hpp>
#include <memory>
using namespace std;
int main()
{
auto document = std::unique_ptr<pugi::xml_document>(new pugi::xml_document);
pugi::xml_node declNode = document->prepend_child(pugi::node_declaration);
declNode.append_attribute("version") = "1.0";
declNode.append_attribute("encoding") = "UTF-8";
declNode.append_attribute("standalone") = "yes";
pugi::xml_node rootNode = document->append_child("Document");
rootNode.append_child("Files");
int err = 0;
zip_t* zip = zip_open("test.zip", ZIP_CREATE, &err);
{
{
std::stringstream ss;
document->save(ss, " ");
std::string buffer = ss.str();
auto src = zip_source_buffer_create(buffer.c_str(),buffer.length(),0,0);
zip_file_add(zip,"Document.xml",src,ZIP_FL_ENC_UTF_8);
}
}
zip_close(zip);
return 0;
}Document.xml :
~U Ä U rsion="1.0" encoding="UTF-8" standalone="yes"?>
<Document>
<Files />
</Document>十六进制:

发布于 2022-09-14 19:57:58
发布的程序由于读取已释放的内存而具有未定义的行为。
在发布的zip_source_t gets使用freep = 0的示例中,您需要确保所提供的缓冲区在zip_source_t对象的整个生存期内保持有效:
zip_source_t * zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error);函数zip_source_buffer()和zip_source_buffer_create()从大小为len的缓冲区数据创建一个zip源。如果freep为非零,则当缓冲区不再需要时将被释放. data 必须在创建的源的生存期内保持有效。 源代码可以用来打开压缩存档。
zip_file_add() (如果成功的话)将获得您给它的源的所有权,但是请注意,它并不需要立即释放源--例如,它可以将它存储在zip_t中。
由于它是当前实现的,zip_file_add()没有释放zip_source_t -而是挂起它,并在调用zip_close()时将其写入。因此,您的缓冲区需要在zip_t对象的整个剩余生存期内保持有效--在本例中,直到调用zip_close()为止。
如果您重写示例以使std::string buffer;处于活动状态,直到关闭zip_t之后,生成的文件应该是正确的:
zip_t* zip = zip_open("test.zip", ZIP_CREATE, &err);
std::stringstream ss;
document->save(ss, " ");
std::string buffer = ss.str();
auto src = zip_source_buffer_create(buffer.c_str(),buffer.length(),0,0);
zip_file_add(zip,"Document.xml",src,ZIP_FL_ENC_UTF_8);
zip_close(zip); // lifetime of zip_t ends here (which will also end the lifetime of the zip_source_t)
// lifetime of buffer ends at end of scope推荐
无法知道zip_source_t将存活多长时间(它是引用计数的),因此很难知道需要多长时间才能使缓冲区存活。
因此,我建议将zip_source_t的内存与malloc()分开分配,并将freep=1传递给zip_source_buffer_create()。
这样,只要zip_source_t还活着,缓冲区就会保持有效。
https://stackoverflow.com/questions/73721970
复制相似问题