lista jednokierunkowa - wyciek pamięci

0

witam,
mam prostą listę jednokierunkową i wygląda na to, że mam wyciek pamięci.
Cały kod: http://wklej.org/id/2269402/
Kod potrzebny do zorientowania się co i jak:

#define MALLOC(type) (type*)malloc(sizeof(type))

typedef struct kosmita{
    struct kosmita *next;
    char name[8];           // nazwa kosmity
    unsigned short int tent_amount; // ilosc czolkow
}kosmita_t;

void add_elements(kosmita_t *head, size_t n)
{
    kosmita_t *current;
    current = head;
    for(int i = 0; i < n; ++i)
    {
        while(current->next != NULL)
            current = current->next;
        current->next = MALLOC(kosmita_t);
        if(current->next == NULL)
        {
            errno = ENOMEM;
            perror("Nie mozna bylo zaalokowac pamieci!");
            exit(EXIT_FAILURE);
        }
        current =  current->next;
        current->tent_amount = rand() % MAX_TENT + 1;
        rand_str(current->name, 8);
    }
    current->next = NULL;
}


int main()
{
    int counter = 0;
    time_t t;
    srand((unsigned int)&t);    
    char choice = 'o';
    size_t n; // niech bedzie n= 10e6
    kosmita_t * head;
    head = MALLOC(kosmita_t);
    if(head == NULL)
    {
        errno = ENOMEM;
        perror("Nie mozna bylo zaalokowac pamieci!");
        exit(EXIT_FAILURE);
    }
    head->next = NULL;
    head->tent_amount = 1;
    strcpy(head->name, "first");
    while(choice != 'q')
    {
        scanf("%c", &choice);
        while(getchar() != '\n');   // clear buffer
        add_elements(head, n);
        while(head != NULL)
        {
            kosmita_t *temp;
            temp = head;
            head = head->next;
            free(temp);
        }
    }
        return 0;
}

Po dodaniu około miliona elementów i przejściu przez while'a na końcu main zajmuje 2-3 MB pamięci, podczas gdy tuż po uruchomieniu programu było koło 500KB. Gdzie jest błąd?

1
  1. Gratulacje z algorytmu dodania do listy z typowym kosztem O(1) zrobiłeś algorytm z kosztem O(N2)
  2. W liście się nie przedziela elementów na początku, tylko dopiero wtedy gdy jest to niezbędne
  3. Stworzyłeś potworka: kosmito-szereg-zoo podziel to na trzy klasy alien, aliennode, alienlist
  4. Klasyczne podejście do listy: http://4programmers.net/Forum/C_i_C++/262765-listy_dodawanie_pierwszego_el?p=1203991#id1203991
5

Masz w kodzie UB.

current->next = MALLOC(kosmita_t);
current =  current->next;

i w następnej iteracji:

while(current->next != NULL)

current->next nie było nigdzie przypisane, a malloc to nie calloc, nie przypisuje od razu wartości.

0
_13th_Dragon napisał(a):

Klasyczne podejście do listy: http://4programmers.net/Forum/C_i_C++/262765-listy_dodawanie_pierwszego_el?p=1203991#id1203991

Przejrzałem to i rzeczywiście, bardzo fajna i elegancka metoda. Porobiłem resztę przypadków (usuń n-ty element, dodaj po n-tym, itd.) i wszystko fajnie, ale z jednym mam problem - zamiana elementów.
Gubię się wśród tych przypadków i zawsze mi jeden adres ucieka, przez co mam nieskończoną listę.
Jak to zrobić (tj. zamiana elementu i-tego z n-tym)?

1

To proste, wymieniaj wartości.
Jeżeli koniecznie chcesz wymieniać adresy wskaźników (co nie jest podejściem sensownym) to posługuj się wskaźnikiem na wskaźnik:

node **tmp=&head; // inicjalizacja.
tmp=&((*tmp)->next); // przestawić na następny.
tmp=&other_double_ptr; // podmiana wskaźnika

1 użytkowników online, w tym zalogowanych: 0, gości: 1