1
votes

When running Valgrind checks, I am getting an 'Invalid read of size 8' which points to the use of a memcpy. The destination field is an empty, uninitialized struct. The source is a the same struct which is a member of another struct.

i.e Destination = Bar, Source = Foo->Bar.

I am assuming the issue lies with the size arg in memcpy. I have tried using sizeof(Foo->Bar), sizeof(Bar) and sizeof(Bar_s).

In header:

struct Foo_s
{
  Bar_t payload;
  //other structs and variables
};

typedef struct
{
    uint64_t timestamp;
    uint16_t id;
} Bar_t;

In c file:

//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));

I am getting the expected behaviour however Valgrind doesn't seem to like how it's being done.

Here is the error:

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
1
The code shown for the header won't compile — unless you have a second identical definition of Bar_t somewhere else. You've not shown how foo_data is defined. And you appear to be handling data from one thread's stack in a second thread, which is dubious at best. There's nothing we can do with the information provided. You'll need to provide something closer to an MCVE (Minimal, Complete, Verifiable Example?) (or MRE or whatever name SO now uses; MCVE was good for over five years and it did not need changing).Jonathan Leffler
If that is the entirety of your C code, you're likely reading uninitialized memory.Andrew Henle
One of the common idiom for a typedef struct is typedef struct S { int s; } S;. Also switch the two struct codes otherwise it will not compile.ooj-001
You should exhibit your working code.snr
Since you use foo_data as a pointer i suspect you did not allocate memory for it correctly. Maybe you have used sizeof(uint64_t) and/or sizeof(uint16_t) for allocation. Note that a structs size is not always the sum of the sizes of its members. I simply added a static definition of foo_data to test your code and i do not get any errors.Yastanub

1 Answers

1
votes

The valgrind message suggests that:

  • in thread 11 you created Foo_s as a local variable, i.e., on stack
  • you started a new thread, thread 36, passing a pointer to that variable
  • thread 36 tries to read data from that pointer
  • but the thread 11 already "left" the function where you created the variable, so the data that the thread 36 tries to read is already invalid

By chance you are still getting valid results when running the program because nothing has overwritten that data yet.