【发布时间】:2021-09-04 21:36:55
【问题描述】:
在测试 filesystem::path 对象的序列化和反序列化时,我有以下代码可以正常工作:
#include <filesystem>
#include <array>
#include <iostream>
int main() {
namespace fs = std::filesystem;
std::array<char, sizeof(fs::path)> arr;
fs::path currentPath("./Icon");
memcpy(&arr[0], ¤tPath, sizeof(fs::path));
currentPath = fs::path("./Characters"); //Change currentPath before performing memcpy deserializing for testing purposes
memcpy(¤tPath, &arr[0], sizeof(fs::path));
std::cout << currentPath.filename();
}
这完美地工作,序列化到字节数组并按预期反序列化。直到我使用不同的文件路径,例如用下面的测试路径交换初始路径:
#include <filesystem>
#include <array>
#include <iostream>
int main() {
namespace fs = std::filesystem;
std::array<char, sizeof(fs::path)> arr;
fs::path currentPath("./Characters");
memcpy(&arr[0], ¤tPath, sizeof(fs::path));
currentPath = fs::path("./Icon"); //Change currentPath before performing memcpy deserializing for testing purposes
memcpy(¤tPath, &arr[0], sizeof(fs::path));
std::cout << currentPath.filename();
}
当我运行这个版本的代码时,currentPath 对象最终被破坏了。
两个不同但真实的目录的不同行为使我相信未定义的行为已在某处溜走,但我不确定确切的位置。同样,文件路径中使用的目录是真实的,但即使不是,我也看不出它为什么会影响路径对象的序列化和反序列化,因为路径对象可用于表示不存在的文件路径。
【问题讨论】:
-
“这很完美”。它可能看起来有效,但它也是错误的,
fs::path不可轻易复制。 -
由于
fs::path是固定大小的,问问自己它如何支持任意大小的路径。唯一可行的方法是包含一个指向堆分配内存的动态容器。因此,您不能复制内存并将其视为已序列化。请改用适当的序列化库/格式。 -
@Jarod42 对象规范是否包含声明对象不可轻易复制的信息?在我使用任何东西之前,我通常会查看 cppreference.com 提供的文档,但我没有在 path 类中看到任何表明它不可轻易复制的内容。
-
对于你不同的行为,也许
path使用了小字符串优化...
标签: c++ serialization path c++17 undefined-behavior