将变量传递给函数会更改 C 中的地址位置

Passing Variable To Function Changes Address Location in C

在将参数传递给函数时遇到一个奇怪的问题。

参数是一个结构体,定义为:

#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)

我有一个函数将此结构声明为:

void func1(void) {
    message_t response;

在这个函数中,我将它作为参数传递给另一个函数:

    func2(response);

func2 中,我声明了另一个结构,它定义为:

 #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)

此结构在 func2 中声明为:

frame_t frame;

frame 会将一些数据复制到其中,其 payload 元素中的数据是我想要复制到 response 结构中的数据。

所以现在 func2 我有一个电话给 memcpy

memcpy((uint8_t *)&response, frame.payload, (frame.header.length - 1));

我已经验证 frame.header.length 等于 20,现在负 1 将复制超过 19 个字节的数据。 response 宽度为 19 个字节,所以应该没问题。

执行memcpy后,我打印出response的内容,内容看起来是正确的。

返回func1后我再次打印response的内容。现在内容没了,又是空的

所以我调试它的方法是在 func1 的上下文中打印 response 的地址位置,然后我得到地址 0x2000a470.

如果我在 func2 的上下文中打印 response 的地址位置,我会得到地址 0x2000a484.

如果我打印从地址 0x2000a484 开始的内存,我会看到应该在 response.

中的数据

为什么 response 的地址在我将它传递给另一个函数后立即发生变化?

还有一些额外的信息,我正在用 C 编写,使用 GCC 和一个 ST Arm Core MCU。

您正在 func1func2 之间传播按值传递。你的代码有一个函数,

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 是按值传递的,你需要制作值以允许你想要的修改:

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
}

这应该可以解决您的问题。