Нужен пример использования mmem в Contiki

Я разрабатываю код для использования в симуляторе COOJA. Я использовал malloc() для всех распределений динамической памяти. Во время симуляции частички COOJA периодически перезапускаются, и, наконец, я получаю сообщение об ошибке, которое говорит мне, что причина в том, что я использую malloc().

Я подумываю использовать специальный класс распределения памяти Contiki под названием «mmem». Я не нашел ни одного примера его использования. Вот пример, в котором я использовал malloc() для выделения памяти строке с именем sent.

Как заменить malloc() на mmem вместо malloc()?

   char *sent;
   sent = (char*)malloc(120);
   strncpy(sent , "example" , 7);
   strncat(sent , "|", 1);

person mahshid    schedule 20.07.2019    source источник
comment
Почему бы вам просто не выделить 120 байт в стеке?   -  person Morten Jensen    schedule 20.07.2019
comment
в моем случае между символом и строкой будет много преобразований, которые меня не интересуют.   -  person mahshid    schedule 20.07.2019
comment
Не думаю, что понимаю. Если вы заранее знаете размер выделения (что предлагает ваш пример кода), почему бы просто не выделить его в стеке? Встроенная разработка на устройствах с низким уровнем ресурсов и динамическое распределение обычно заканчивается фрагментацией, которая приводит к истощению ресурсов, что может быть причиной сбоя. Об этом упоминается даже в документации Contiki. Тем не менее, я предполагаю, что вы читали это руководство: github.com/contiki -os / contiki / wiki /?   -  person Morten Jensen    schedule 20.07.2019
comment
Я не уверен, полностью ли понимаю решение, о котором вы говорите. не могли бы вы объяснить, как я могу разместить в стеке? честно говоря, я не понимаю, что вы имели в виду под стеком.   -  person mahshid    schedule 20.07.2019
comment
Стек против кучи - центральная концепция программирования на C, и мне будет сложно объяснить ее здесь, используя всего 600 символов. Обычно вместо char* sent = malloc(120); вы делаете char sent[120]; и т. Д.   -  person Morten Jensen    schedule 21.07.2019
comment
логика кода работает со строками. строки будут отправляться и приниматься, объединяться и много редактироваться. используя char sent[120], я должен иметь дело со 120 символами и преобразовывать их в строку и возвращать обратно много раз. Я выбрал указатели вместо массивов, чтобы упростить работу со строками и избежать сложности.   -  person mahshid    schedule 21.07.2019
comment
В C массив символов - это строка? В char sent[120]; sent - это указатель на символ, как если бы вы сделали char* sent = malloc(120);. Память просто выделяется в стеке, а не в куче.   -  person Morten Jensen    schedule 21.07.2019
comment
Я новичок в C, поэтому не понимаю, что происходит с кучей или стеком. но я узнал, что мы представляем строку с помощью массива символов отсюда: [tutorialspoint.com/cprogramming/c_strings < / а>]. Я ошибся?   -  person mahshid    schedule 21.07.2019
comment
Это в точности моя точка зрения: строка - это массив символов, независимо от того, размещена ли она в стеке или в куче. Выделение кучи - это просто плохая идея для устройств с ограниченными ресурсами, поэтому я советую вам распределять статически вместо этого, независимо от любых предполагаемых преимуществ простоты от динамического распределения.   -  person Morten Jensen    schedule 21.07.2019


Ответы (1)


Из Github Wiki от Contiki

Вот пример того, как использовать распределитель управляемой памяти:

 #include "contiki.h"
 #include "lib/mmem.h"

 static struct mmem mmem;

 static void
 test_mmem(void)
 {
   struct my_struct {
     int a;
   } my_data, *my_data_ptr;

   if(mmem_alloc(&mmem, sizeof(my_data)) == 0) {
     printf("memory allocation failed\n");
   } else {
     printf("memory allocation succeeded\n");
     my_data.a = 0xaa;
     memcpy(MMEM_PTR(&mmem), &my_data, sizeof(my_data));
     /* The cast below is safe only if the struct is packed */
     my_data_ptr = (struct my_struct *)MMEM_PTR(&mmem);
     printf("Value a equals 0x%x\n", my_data_ptr->a);
     mmem_free(&mmem);
   }
 }

В приведенном выше примере показан базовый пример использования библиотеки управляемой памяти. В строке 4 мы выделяем переменную mmem, которая идентифицирует объект управляемой памяти, который мы собираемся выделить. В строке 13 мы используем переменную mmem в качестве аргумента для mmem_alloc (), чтобы выделить место для структуры sizeof (my_data) байтов. Если распределение прошло успешно, мы копируем значения из существующей структуры в выделенную структуру, на которую указывает MMEM_PTR (& mmem). Затем к отдельным членам выделенной структуры можно получить доступ посредством преобразования типа MMEM_PTR (& mmem) в структуру my_struct *, как показано в строке 20. Обратите внимание, что приведение безопасно только в том случае, если структура упакована. Наконец, управляемая память освобождается в строке 21 вызовом mmem_free ().

.

РЕДАКТИРОВАТЬ:

Судя по коду, который вы вставили в комментарии, нет необходимости использовать malloc или mmem-модуль. Просто выделите в стеке. Может, вместо этого попробуйте что-нибудь вроде этого:

/* Allocate memory on the stack */
char sent[120];

/* Manipulate strings */
strncpy(sent , "reqid" , 5); 
strncat(sent, "|", 1); 

/* Send UDP packet */
uip_udp_packet_send(mcast_conn, sent, strlen(sent)); 

/* Print out string sent */
printf(" (msg: %s)\n", sent); 

ИЗМЕНИТЬ 2:

Вот страница о куче и стеке. и вопрос о динамическом распределении на встроенных устройствах и связанных с ним проблемах.

person Morten Jensen    schedule 20.07.2019
comment
собственно я видел этот пример. чтобы прояснить проблему, я вставляю сюда свой код: `struct my_struct {char * sent; } my_data, * my_data_ptr; strncpy (my_data.sent, reqid, 5); strncat (my_data.sent, |, 1); memcpy (MMEM_PTR (& mmem), & my_data, sizeof (my_data)); my_data_ptr = (struct my_struct *) MMEM_PTR (& mmem); uip_udp_packet_send (mcast_conn, my_data_ptr- ›отправлено, strlen (my_data_ptr-› отправлено)); printf ((msg:% s) \ n, my_data_ptr- ›отправлено); mmem_free (& mmem); `Я ожидаю увидеть mg: reqid | в выводе, но вывод в NULL. Я хочу знать, где я делаю не так. - person mahshid; 20.07.2019
comment
@mahshid Не могли бы вы отредактировать свой вопрос, включив в него код, который вы пробовали? Вам не хватает звонка на mmem_init() и mmem_alloc(...), я думаю ...? Я снова предлагаю вам попробовать использовать статическое распределение вместо динамического по причинам, указанным в других моих комментариях (фрагментация, приводящая к исчерпанию памяти). - person Morten Jensen; 21.07.2019
comment
извините за плохое представление, я пробовал несколько раз, но не мог понять, как это работает. Я добавил mmem_init () и mmem_allocate (), но он все тот же. C struct my_struct { char * sent; } my_data, *my_data_ptr; mmem_init(); mmem_alloc(&mmem, 120); strncpy(my_data.sent , "reqid" , 5); strncat(my_data.sent, "|", 1); memcpy(MMEM_PTR(&mmem), &my_data, sizeof(my_data)); my_data_ptr = (struct my_struct *)MMEM_PTR(&mmem); uip_udp_packet_send(mcast_conn, my_data_ptr->sent, strlen(my_data_ptr->sent)); printf(" (msg: %s)\n", my_data_ptr->sent); mmem_free(&mmem); - person mahshid; 21.07.2019
comment
@mahshid Я обновил свой ответ некоторым кодом, который, как мне кажется, мог бы работать вместо этого. У меня ничего не работает с Contiki, поэтому я не могу проверить это сам, но я не думаю, что вам нужен mmem-модуль из того, что вы разместили. - person Morten Jensen; 21.07.2019