【发布时间】:2019-06-11 13:57:13
【问题描述】:
在运行 Valgrind 检查时,我得到一个“大小为 8 的无效读取”,这表明使用了 memcpy。目标字段是一个空的、未初始化的结构。源是同一个结构,它是另一个结构的成员。
即目的地 = 酒吧,来源 = Foo->酒吧。
我假设问题在于 memcpy 中的大小 arg。我尝试过使用 sizeof(Foo->Bar)、sizeof(Bar) 和 sizeof(Bar_s)。
在标题中:
struct Foo_s
{
Bar_t payload;
//other structs and variables
};
typedef struct
{
uint64_t timestamp;
uint16_t id;
} Bar_t;
在c文件中:
//Foo_s is passed into the function already populated, let's call it foo_data
Bar_t payload_data;
memcpy(&payload_data, &(foo_data->payload_data), sizeof(foo_data->payload_data));
我得到了预期的行为,但是 Valgrind 似乎不喜欢它的完成方式。
这是错误:
Thread 36 function_name:47/101:
==774== Invalid read of size 8
==774== at 0x1C1E59: function_name (in /path/to/exe)
==774== by 0x189065: another_function (in /path/to/exe)
==774== by 0x5D544A3: another_function2 (pthread_create.c:456)
==774== Address 0x40bb6b8 is on thread 11's stack
==774== 1896 bytes below stack pointer
【问题讨论】:
-
标头显示的代码不会编译——除非您在其他地方有第二个相同的
Bar_t定义。您还没有展示如何定义foo_data。而且您似乎正在第二个线程中处理来自一个线程堆栈的数据,这充其量是可疑的。我们对提供的信息无能为力。您需要提供更接近 MCVE (Minimal, Complete, Verifiable Example?) 的内容(或 MRE 或 SO 现在使用的任何名称;MCVE 已经使用了五年多,不需要更改)。 -
如果这是您的全部 C 代码,您可能正在读取未初始化的内存。
-
typedef 结构的一个常见习语是
typedef struct S { int s; } S;。还要切换两个struct代码,否则编译不出来。 -
你应该展示你的工作代码。
-
由于您使用
foo_data作为指针,我怀疑您没有为它正确分配内存。也许您已经使用sizeof(uint64_t)和/或sizeof(uint16_t)进行分配。请注意,结构的大小并不总是其成员大小的总和。我只是添加了foo_data的静态定义来测试您的代码,我没有收到任何错误。