URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 3257
[ Назад ]

Исходное сообщение
"Рост программы в памяти"

Отправлено Brick , 09-Авг-04 14:17 
Добрый день.

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

/////////////////////////////////////////////////////////////////
long getRuleCount(const char *id)
{
   static int s = -1;      /* the socket */

   struct ip_fw *r;

#define NEXT(r) ((struct ip_fw *)((char *)r + RULESIZE(r)))

   int seen = 0, nbytes;
   long bytes = 0;
   u_long rnum;
   char rule[7];

   int nalloc = 1024;   /* start somewhere... */


   /* get rules or pipes from kernel, resizing array as necessary */
   nbytes = nalloc;

   if (s == -1)
      s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
   if (s < 0)
      send_error("socket error(IPFW)");

   r = NULL;

   while (nbytes >= nalloc)
   {
      nalloc = nalloc * 2 + 200;
      nbytes = nalloc;

      if ((r = (ip_fw*)realloc(r, nbytes)) == NULL)
      {   }

   sprintf(rule, "%s%s", (IPFW_PREFIX), id);
   rnum = atoi(rule);

   for (int n = seen = 0; n < 65535, r->rulenum <= rnum; n++, r = NEXT(r))
   {
      if (r->rulenum == rnum)
      {
         bytes += (long)r->bcnt;
         seen = 1;
      }
   }

   if (!seen)
   {
      char err[50];
      sprintf(err, "Rule %lu does not exist", rnum);
      send_error(err);

      return -1;
   }

#undef NEXT


   return bytes;
}
         send_error("Error on realloc (IPFW)");

         return -1;
      }

/////////////////////////////////////////////////////////////////


Содержание

Сообщения в этом обсуждении
"Рост программы в памяти"
Отправлено Vladislav Lazarenko , 10-Авг-04 12:59 
>Добрый день.
>
>Подскажите, пожалуйста, почему данная функция при переодическом выполнении вызывает рост программы в
>памяти и каким образом это можно исправить.
>
>/////////////////////////////////////////////////////////////////
>long getRuleCount(const char *id)
>{
>   static int s = -1;    
> /* the socket */
>
>   struct ip_fw *r;
>
>#define NEXT(r) ((struct ip_fw *)((char *)r + RULESIZE(r)))
>
>   int seen = 0, nbytes;
>   long bytes = 0;
>   u_long rnum;
>   char rule[7];
>
>   int nalloc = 1024;   /* start somewhere...
>*/
>
>
>   /* get rules or pipes from kernel, resizing array
>as necessary */
>   nbytes = nalloc;
>
>   if (s == -1)
>      s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
>   if (s < 0)
>      send_error("socket error(IPFW)");
>
>   r = NULL;
Тут мы проинициализировали указатель нулевым значением ...

>
>   while (nbytes >= nalloc)
>   {
>      nalloc = nalloc * 2 +
>200;
>      nbytes = nalloc;
>
>      if ((r = (ip_fw*)realloc(r, nbytes)) ==
>NULL)
>      {   }
>
Тут конечно все грязно, без обработки ошибок, но .. Тут ты выделяешь динамическую память, если указатель будет нулевым, или перевыделяешь память, если указатель ен нулевой ... Как результат - выделенная динамическая память ...

>   sprintf(rule, "%s%s", (IPFW_PREFIX), id);
>   rnum = atoi(rule);
>
>   for (int n = seen = 0; n < 65535, r->rulenum <= rnum; n++, r = NEXT(r))
>   {
>      if (r->rulenum == rnum)
>      {
>         bytes += (long)r->bcnt;
>         seen = 1;
>
>      }
>   }
>
>   if (!seen)
>   {
>      char err[50];
>      sprintf(err, "Rule %lu does not exist",
>rnum);
>      send_error(err);
>
>      return -1;
>   }
>
>
>
>#undef NEXT
>
>
>   return bytes;
>}
>         send_error("Error on realloc
>(IPFW)");
>
>         return -1;
>      }
>
>/////////////////////////////////////////////////////////////////


Которую ты нигде не освободил.

Итак, при многократном выполнеини твоей программы выделается все больше и больше динамической памяти...

Исправляй, man free. Творческих тебе узбеков :)


"Рост программы в памяти"
Отправлено Brick , 10-Авг-04 13:54 
Пробовал free(r):
a.out in free(): error: pointer to wrong page
Abort trap (core dumped)
я ведь смещаю указатель в цыкле и оно, видимо не знает чего высвобождать, пробовал не смещать (неработоспособный вариант) всё-равно память растёт... :(

"Рост программы в памяти"
Отправлено Brick , 10-Авг-04 13:58 
исправляюсь: если не смещать указатель - память дружелюбно высвобождается и роста нет, как мне её высвободить в этом случае???

"Рост программы в памяти"
Отправлено Vladislav Lazarenko , 10-Авг-04 14:02 
>исправляюсь: если не смещать указатель - память дружелюбно высвобождается и роста нет,
>как мне её высвободить в этом случае???

Конечно освобождения "левого" указателя ничего не даст. Перед тем, как смешать r, сохрани его копию. Например:

void *copy_of_r = (void *)r;

И перед возвратом управления:

free(copy_of_r);

....

удачи.


"Рост программы в памяти"
Отправлено Brick , 10-Авг-04 14:03 
Всё спасибо, разобрался: перед цыклом, где был перебор правил надо было обьявить новый указатель, типа: struct ip_fw *rul = r;

"Рост программы в памяти"
Отправлено Vladislav Lazarenko , 10-Авг-04 14:04 
>Всё спасибо, разобрался: перед цыклом, где был перебор правил надо было обьявить
>новый указатель, типа: struct ip_fw *rul = r;


Вообще загляни в ipfw.c ... Там есть прекрасный пример перебора правил брандмауэра)))


"Рост программы в памяти"
Отправлено Brick , 11-Авг-04 10:17 
>>Всё спасибо, разобрался: перед цыклом, где был перебор правил надо было обьявить
>>новый указатель, типа: struct ip_fw *rul = r;
>
>
>Вообще загляни в ipfw.c ... Там есть прекрасный пример перебора правил брандмауэра)))
>
я оттуда и взял ;)