Утечка памяти, не могу понять где
От: Tasheehoo  
Дата: 24.11.16 13:42
Оценка:
Хочу реализовать пул нодов(node) на основе двусвязного списка для С, и получился такой код:

#include <stdlib.h>
#include <string.h>

struct item_t {
    void *next;
};
typedef struct item_t item_t;

item_t *pool_root = NULL, *pool_last = NULL;

void put_elem_mem(item_t *sv)
{
  if (!sv || sv->next != NULL)
    return;

  if (pool_last == NULL)
    pool_root = pool_last = sv;
  else
    pool_last->next = sv;
}

item_t* get_elem_mem()
{
  item_t *r = NULL;
  if ((r = pool_root) == NULL)
  {
    r = malloc(sizeof(struct item_t));
    r->next = NULL;
    
    return r;
  }

  if((pool_root = r->next) == NULL)
    pool_last = NULL;

  r->next = NULL;

  return r;
}

int main() {
    while (1) {
        void *p0 = get_elem_mem();
        void *p1 = get_elem_mem();
        void *p2 = get_elem_mem();
        
        put_elem_mem(p0);
        put_elem_mem(p1);
        put_elem_mem(p2);
    }
}

Тут в main() если создавать один или два нода — память не течет. Но если создавать три и более — течет.
Чесслово, три часа не могу понять где я ошибся. Помогите пожалуйста.
Re: Утечка памяти, не могу понять где
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 24.11.16 13:53
Оценка:
Здравствуйте, Tasheehoo, Вы писали:

T>

T>#include <stdlib.h>
T>#include <string.h>

T>struct item_t {
T>    void *next;
T>};
T>typedef struct item_t item_t;

T>item_t *pool_root = NULL, *pool_last = NULL;

T>void put_elem_mem(item_t *sv)
T>{
T>  if (!sv || sv->next != NULL)
T>    return;

T>  if (pool_last == NULL)
T>    pool_root = pool_last = sv;
T>  else
T>    pool_last->next = sv;
T>}

T>item_t* get_elem_mem()
T>{
T>  item_t *r = NULL;
T>  if ((r = pool_root) == NULL)
T>  {
T>    r = malloc(sizeof(struct item_t)); //а free к нему где?
    r->>next = NULL;
    
T>    return r;
T>  }

T>  if((pool_root = r->next) == NULL)
T>    pool_last = NULL;

  r->>next = NULL;

T>  return r;
T>}

T>int main() {
T>    while (1) {
T>        void *p0 = get_elem_mem();
T>        void *p1 = get_elem_mem();
T>        void *p2 = get_elem_mem();
        
T>        put_elem_mem(p0);
T>        put_elem_mem(p1);
T>        put_elem_mem(p2);
T>    }
T>}

T>

T>Тут в main() если создавать один или два нода — память не течет. Но если создавать три и более — течет.
T>Чесслово, три часа не могу понять где я ошибся. Помогите пожалуйста.
Ни одного free я не увидел, а список у тебя односвязанный.
Sic luceat lux!
Re: Утечка памяти, не могу понять где
От: andrey.desman  
Дата: 24.11.16 14:01
Оценка: +2
Здравствуйте, Tasheehoo, Вы писали:

T>

T>void put_elem_mem(item_t *sv)
T>{
T>  if (!sv || sv->next != NULL)
T>    return;

T>  if (pool_last == NULL)
T>    pool_root = pool_last = sv;
T>  else
T>    pool_last->next = sv;
// pool_last обновить надо бы
T>}
T>
Re[2]: Утечка памяти, не могу понять где
От: Tasheehoo  
Дата: 24.11.16 14:02
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Ни одного free я не увидел, а список у тебя односвязанный.

Тогда почему при создании одного или двух нодов в цикле память не течет?
Re[2]: Утечка памяти, не могу понять где
От: Tasheehoo  
Дата: 24.11.16 14:05
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>// pool_last обновить надо бы

Я не понимаю что я должен тут сделать...
Re[2]: Утечка памяти, не могу понять где
От: Tasheehoo  
Дата: 24.11.16 14:07
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>// pool_last обновить надо бы

Новерное так?
void put_elem_mem(item_t *sv)
{
  if (!sv || sv->next != NULL)
    return;

  if (pool_last == NULL)
    pool_root = pool_last = sv;
  else
    pool_last->next = sv;
  
  pool_last = pool_last->next;
}
Re[3]: Утечка памяти, не могу понять где
От: uzhas Ниоткуда  
Дата: 24.11.16 14:08
Оценка: +1
Здравствуйте, Tasheehoo, Вы писали:

AD>>// pool_last обновить надо бы

T>Я не понимаю что я должен тут сделать...

при добавлении элемента в список надо выставить и root и last
после добавления last должен указывать на только что вставленный элемент
root выставляется только один раз, когда список пустой, то есть когда root == NULL
Re[3]: Утечка памяти, не могу понять где
От: andrey.desman  
Дата: 24.11.16 14:08
Оценка: +1
Здравствуйте, Tasheehoo, Вы писали:

AD>>// pool_last обновить надо бы

T>Я не понимаю что я должен тут сделать...

void put_elem_mem(item_t *sv)
{
  if (!sv || sv->next != NULL)
    return;

  if (pool_last == NULL)
    pool_root = pool_last = sv;
  else
  {
    pool_last->next = sv;
    pool_last = sv;
  }
// pool_last у тебя здесь не меняется. Он один раз устанавливается в первой ветке if и
// по сути всегда равен pool_root. Вызываешь функцию трижды и второй нод теряешь.
// Как сделать см. выше
}
Отредактировано 24.11.2016 14:12 andrey.desman . Предыдущая версия .
Re[3]: Утечка памяти, не могу понять где
От: andrey.desman  
Дата: 24.11.16 14:09
Оценка: +1
Здравствуйте, Tasheehoo, Вы писали:

AD>>// pool_last обновить надо бы

T>Новерное так?

Не так. Если пошли по первой ветке, то pool_last = pool_last->next нельзя делать, иначе ты тут же потеряешь свой pool_last (он станет NULL).

T>
T>void put_elem_mem(item_t *sv)
T>{
T>  if (!sv || sv->next != NULL)
T>    return;

T>  if (pool_last == NULL)
T>    pool_root = pool_last = sv;
T>  else
T>    pool_last->next = sv;
  
T>  pool_last = pool_last->next;
T>}
T>
Отредактировано 24.11.2016 14:11 andrey.desman . Предыдущая версия .
Re[3]: Утечка памяти, не могу понять где
От: uzhas Ниоткуда  
Дата: 24.11.16 14:11
Оценка:
Здравствуйте, Tasheehoo, Вы писали:

T>Новерное так?


ошибочка
может, так? :
void put_elem_mem(item_t *sv)
{
  if (!sv || sv->next != NULL)
    return;

  if (pool_root == NULL)
    pool_root = sv;
  else
    pool_last->next = sv; //pool_last != NULL here
  
  pool_last = sv;
}
Re[4]: Утечка памяти, не могу понять где
От: Tasheehoo  
Дата: 24.11.16 14:17
Оценка:
Здравствуйте, uzhas, Вы писали:

U>при добавлении элемента в список надо выставить и root и last

U>после добавления last должен указывать на только что вставленный элемент
U>root выставляется только один раз, когда список пустой, то есть когда root == NULL
Я понял! Всем спасибо!
Re[4]: Утечка памяти, не могу понять где
От: Tasheehoo  
Дата: 24.11.16 14:18
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Не так. Если пошли по первой ветке, то pool_last = pool_last->next нельзя делать, иначе ты тут же потеряешь свой pool_last (он станет NULL).

Я понял! Спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.