sách gpt4 ai đã đi

c++ - 内存清理程序错误 : clang5 + msan + fwrite of structs with padding bytes

In lại 作者:塔克拉玛干 更新时间:2023-11-03 07:06:55 27 4
mua khóa gpt4 Nike

最小示例:

#include 

struct TFoo
{
bool Field1_ = false;
uint64_t Field2_ = 0;
};

int chính() {
TFoo Foo_{};
const char* filename = "text.txt";
std::ofstream f(filename);

f.write((char*)(&Foo_), sizeof(Foo_));
}

clang 自第 5 版以来在 msan 中报告如下内容:

Uninitialized bytes in __interceptor_fwrite at offset 0 inside [0x720000000000, 15)
==71928==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x2823aa (/home//test-ofstream+0x2823aa)
#1 0x27830f (/home//test-ofstream+0x27830f)
#2 0x272757 (/home//test-ofstream+0x272757)
#3 0x271388 (/home//test-ofstream+0x271388)
#4 0x270c96 (/home//test-ofstream+0x270c96)
#5 0x2709e2 (/home//test-ofstream+0x2709e2)
#6 0x26ff9e (/home//test-ofstream+0x26ff9e)
#7 0x7fbc7238382f (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

这是因为Field1_Field2_之间的填充字节没有初始化。

没关系,MSAN是对的。

但是如果代码包含此类代码的非常大的示例(将结构保存到二进制文件),是否有任何漂亮的方法可以大量改进代码?

(打包结构不是我们的解决方案。)

1 Câu trả lời

如果你能改变struct TFoo的定义,你可以像这样添加一个构造函数:

struct TFoo {
bool Field1_;
uint64_t Fields_;
TFoo() { memset(this, 0, sizeof(*this)); }
TFoo(const TFoo &rhs) : TFoo() { Field1_ = rhs.Field1_; Field2_ = rhs.Field2_; }
};

我认为您不能根据标准以这种方式使用memset,但它可能适用于您的编译器。参见 How can I zero just the padding bytes of a class? ,其中讨论了此解决方案。

原始答案

我想到了将 Field1_Field2_ 之间的填充字节清零。但老实说,我不确定它是否符合标准。当然,TFoo 对象的某种序列化会好得多,但如果我理解正确的话,这不是你的选择,是吗?

struct TFoo
{
bool Field1_ = false;
uint64_t Field2_ = 0;
};

struct TFooWrapper {
union {
TFoo tfoo;
char dummy[sizeof(TFoo)] = { 0 };
} u;
};

làm mới

Từ http://en.cppreference.com/w/cpp/language/union : 至多一个变体成员可以有一个默认的成员初始值设定项。 因此上面的代码可能不正确。但是您可以,例如,为 TFooWrapper 定义默认构造函数以将所有字节清零。

关于c++ - 内存清理程序错误 : clang5 + msan + fwrite of structs with padding bytes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48458115/

27 4 0
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com