【问题标题】:'Invalid read of Size 8' - Valgrind. Trying to populate struct with data from other struct'无效读取大小 8' - Valgrind。试图用来自其他结构的数据填充结构
【发布时间】: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 的静态定义来测试您的代码,我没有收到任何错误。

标签: c struct valgrind memcpy


【解决方案1】:

valgrind 消息表明:

  • 在线程 11 中,您将 Foo_s 创建为局部变量,即在堆栈上
  • 您启动了一个新线程,线程 36,将指针传递给该变量
  • 线程 36 尝试从该指针读取数据
  • 但线程 11 已经“离开”了您创建变量的函数,因此线程 36 尝试读取的数据已经无效

运行程序时,您可能仍然得到有效结果,因为尚未覆盖该数据。

【讨论】:

  • 感谢您的回答!这与我们在另一位工程师查看时得出的结论相同。结果仍然有效,但是我们现在知道情况可能并非总是如此,这取决于 MMU 重新分配该线程堆栈位于内存中的内存的速度。至少这是我们的理解,我们是对 C 来说还是很新。我们决定改用全局变量和互斥体来重写它。
猜你喜欢
  • 2012-08-22
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
相关资源
最近更新 更多