Reputation: 415
Having an odd issue here with passing an argument to a function.
The argument is a struct, defined as:
#pragma pack(push,1)
typedef struct {
struct {
uint8_t opcode;
uint8_t type;
union {
uint8_t attr;
struct {
unsigned int reserved : 6;
unsigned int sequence : 2;
};
};
uint8_t bytes;
} header;
uint8_t payload[15];
} message_t;
#pragma pack(pop)
I have a function that declares this struct as:
void func1(void) {
message_t response;
Within this function I pass it as an argument to another function:
func2(response);
Within func2
I have another struct declared and it is defined as:
#pragma pack(push,1)
typedef struct {
struct {
uint8_t op_code;
avneraIDs_t IDs;
uint8_t length;
} header;
uint8_t payload[30];
} frame_t;
#pragma pack(pop)
This struct is declared within func2
as:
frame_t frame;
frame
will have some data copied into it, and the data within its payload
element is what I want copied into the response
struct.
So now in func2
i have a call to memcpy
.
memcpy((uint8_t *)&response, frame.payload, (frame.header.length - 1));
I have verified that frame.header.length
is equal to 20, and now minus 1 would copy over 19 bytes of data. response
has a width of 19 bytes so it should be fine.
After performing the memcpy
, I print out the contents of response
and the contents look correct.
After returning to func1
I print the contents of response
again. And now the contents are gone, it's empty again.
So what I did to debug this was I printed the address location of response
within the context of func1
and I get the address 0x2000a470
.
If I print the address location of response
within the context of func2
I get the address 0x2000a484
.
If I print the memory starting at address 0x2000a484
, I see the data that should be in response
.
Why did the address for response
change as soon as I passed it to another function?
Also as some extra information, I am writing in C, using GCC, and an ST Arm Core MCU.
Upvotes: 1
Views: 80
Reputation: 66234
You're propagating pass-by-value between func1
and func2
. Your code has a function,
void func2(message_t response) // <<==== response gets value from caller
{
memcpy(&response, ....) // <<==== modify local response; caller is unaffected.
}
void func1()
{
message_t respnose;
func2(response); // <<==== PASSED BY VALUE
}
C being pass-by-value, you need to craft the value to allow the modification you want:
void func2(message_t *response) // <<==== receiving address of caller's response
{
memcpy(response, ...); // <<=== using address of caller's response.
}
void func1()
{
message_t response;
func2(&response); // <<==== passing address of our response
}
That should fix your issue.
Upvotes: 2