Проблема выделения памяти для глобальной структуры и освобождения ее - PullRequest
0 голосов
/ 20 апреля 2019

Я использую встроенную плату с FreeRTOS.

В задаче я определил две структуры и использую pvPortMalloc для выделения памяти. (Одна структура является членом другой)

Кроме того, я передаю адрес структуры некоторым функциям.

Однако при освобождении памяти с использованием vPortFree.

возникают некоторые проблемы.

Ниже указан мой код (test_task.c):

/* Struct definition */
typedef struct __attribute__((packed)) {

        uint8_t  num_parameter;
        uint32_t member1;
        uint8_t  member2;
        uint8_t  *parameter;

}struct_member;

typedef struct __attribute__((packed)) {

        uint16_t num_member; 
        uint32_t class;
        struct_member *member;

}struct_master;

Я определяю глобальную структуру и массив ниже.

uint8_t       *arr;
struct_master master:

Определение функции:

void decode_func(struct_master *master, uint8_t *arr) 
{
   master->member = pvPortMalloc(master->num_member);

   for(int i = 0; i < scr->num_command; ++i){
      master->member[i].parameter = pvPortMalloc(master->member[i].num_parameter);
      do_something();
   }  
}

Операционная задача показана ниже.

В конце задания я хотел бы освободить память:

void test_task()
{
  decode_func( &master, arr);
  do_operation(); 


  vPortFree(master.member);
  for (int i = 0; i < master.num_member; ++i)
      vPortFree(master.member[i].parameter);

  hTest_task = NULL;
  vTaskDelete(NULL);    
}

Это нормально, чтобы освободить master.member.

Однако, когда программа попробовала бесплатно master.member[i].parameter, кажется, что освобождение было выполнено раньше, и программное обеспечение просто сбрасывалось автоматически.

Кто-нибудь знает, почему так произошло?

Ответы [ 2 ]

0 голосов
/ 21 апреля 2019

На первый взгляд неправильный способ распределения членов в decode_func.

Я предполагаю, что master->num_member указывает количество struct member s, которое должно содержать master.

master->member = pvPortMalloc(master->num_member);

должно быть исправлено на,

master->member = pvPortMalloc(master->num_member * sizeof(struct_member));

Опять же, в той же функции цикл кажется немного подозрительным.

   for(int i = 0; i < scr->num_command; ++i){
      master->member[i].parameter = pvPortMalloc(master->member[i].num_parameter);
      do_something();
   } 

Яне уверен, что указывает src->num_command, но я считаю, что цикл должен выполняться до i < master->num_member.Я предполагаю, что ваш цикл также должен быть обновлен следующим образом:

   for(int i = 0; i < master->num_member; ++i){
      master->member[i].parameter = pvPortMalloc(master->member[i].num_parameter * sizeof(uint8_t));
      do_something();
   } 

Выполняя освобождение памяти, убедитесь, что вы сначала освободили содержащиеся элементы, прежде чем освобождать структуру контейнера.Поэтому сначала вы должны освободить все parameter s, а затем member, поэтому измените этот порядок и в функции test_task.

Также убедитесь, что перед выполнением vTaskDelete(NULL); вы должны освободить всересурсы, потребляемые test_task, в противном случае произойдет утечка ресурсов.vTaskDelete(NULL) просто пометит TCB этой конкретной задачи как ready to be deleted, чтобы через некоторое время простоя задача очистила ресурсы, связанные с TCB.

0 голосов
/ 20 апреля 2019

Как правило, когда вы освобождаете объект, содержимое объекта уничтожается, и вы больше не можете получить к ним доступ.Поэтому, когда вы хотите освободить вложенные выделения, как это, вам нужно освободить внутренние выделения first и только после этого освободить внешнее (master) распределение.Другими словами:

for (int i = 0; i < master.num_member; ++i)
    vPortFree(master.member[i].parameter);
vPortFree(master.member);

сначала освобождают параметры, а затем содержащий массив элементов.

...