Передача переменной в функцию изменяет расположение адреса в C - PullRequest
0 голосов
/ 28 июня 2018

Странная проблема с передачей аргумента функции.

Аргумент - это структура, определяемая как:

#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. А теперь содержимое ушло, снова пусто.

Итак, для отладки я распечатал адрес response в контексте func1 и получил адрес 0x2000a470.

Если я распечатаю адрес местоположения response в контексте func2, я получу адрес 0x2000a484.

Если я распечатываю память, начиная с адреса 0x2000a484, я вижу данные, которые должны быть в response.

Почему адрес для response изменился, как только я передал его другой функции?

Также в качестве дополнительной информации я пишу на C, используя GCC и MC Arm ST Arm Core.

1 Ответ

0 голосов
/ 28 июня 2018

Вы передаете передачу по значению между func1 и func2. Ваш код имеет функцию,

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
}

Это должно исправить вашу проблему.

...