C - dodawanie elementu do listy jednokierunkowej

0

Wiem, że na internecie jest od groma przykładów na stworzenie listy jednokierunkowej, jednak mój program jest dość specyficzny i nie mogę wykminić, co jest w nim nie tak.

Struktury prezentują się następujaco:

typedef struct l_zesp
	{
		union Rzecz
		{
			int a_int;
			double a_double;
		} rzeczywista;

		int uroj;
		int is_double;
	} L_zesp;

typedef struct container
{
	L_zesp* zesp;
	struct container* next;
} Container;

Funkcja dodająca:

void add(Container* glowa,L_zesp* zespol) {
	Container* e, *tmp;
     
     e = (Container*) malloc(sizeof(Container));     
     e->zesp=zespol;

     if (glowa == NULL)     
      {
        e->next = glowa;
        glowa = e;
      }
      else
       { 
         tmp = glowa;
         while (tmp->next != NULL)
            tmp=tmp->next;          
            tmp->next = e;
            e->next = NULL; 
       }
}

Oraz program główny:

int main()
{
	Container *glowa=NULL;
	 L_zesp* k;

	 k=(L_zesp*) malloc (sizeof(L_zesp));
	 k->rzeczywista.a_double=6.33;
	 k->uroj=3;
	 k->is_double=1;
	 add(glowa,k);
	 return 0;
}

Po zabawie debuggerem doszedłem do tego, że w chwili wychodzenia z procedury add głowa tak jakby "traci" swoją wartość i na powrót staje się nullem. W jaki sposób można by temu zaradzić?

1

przekaż adres wskaźnika. Robiąc tak jak masz teraz w funkcji add jest tworzona kopia wskaźnika który wysyłasz w main

0

Dzięki, wygląda na to, że działa :) Wyszło coś takiego, mam tylko nadzieję, że cała reszta jest w miarę w porządku.
Funkcja

void add(Container** glowa,L_zesp* zespol) {
	Container* e, *tmp;
     
     e = (Container*) malloc(sizeof(Container));     
     e->zesp=zespol;

     if (*glowa == NULL)     
      {
        e->next = *glowa;
        *glowa = e;
      }
      else
       { 
         tmp = *glowa;
         while (tmp->next != NULL)
            tmp=tmp->next;          
            tmp->next = e;
            e->next = NULL; 
       }
}

I program główny:

int main()
{
	Container *glowa=NULL;
	 L_zesp* k;

	 k=(L_zesp*) malloc (sizeof(L_zesp));
	 k->rzeczywista.a_double=6.33;
	 k->uroj=3;
	 k->is_double=1;
	 add(&glowa,k);

	 k=(L_zesp*) malloc (sizeof(L_zesp));
	 k->rzeczywista.a_int=4;
	 k->uroj=1;
	 k->is_double=0;
         add(&glowa, k);

        wypisz_liste(glowa);
	return 0;
}
0

Mała podpowiedź- zamiast tego:

         tmp = *glowa;
         while (tmp->next != NULL)
            tmp=tmp->next;          
            tmp->next = e;
            e->next = NULL; 
      
 

Stwórz sobie dodatkową strukturę(taką jak glowa), która będzie ci wskazywać na KONIEC listy dzięki czemu nie będziesz musiał przechodzić przez wszystkie elementy.

0

Program dość ostro rozwinął się przez noc, radę z braku czasu zastosuję już przy następnym, ale teraz piszę, bo mam mały problem z czymś innym. Mianowicie zassałem sobie Visual Leak Detector, który wykrył mi dwa malutkie (104 bajty) wycieki pamięci. Po wyłączaniu poszczególnych częsci programu doszedłem do wniosku, że winowajcą jest ta oto funkcja:

L_zesp* sum(Container* glowa) {
	L_zesp* liczba;
	Container* tmp=glowa;

	liczba=(L_zesp*) malloc(sizeof(L_zesp));
	liczba->uroj=0;
	liczba->rzeczywista.a_double=0;
	liczba->rzeczywista.a_int=0;

	while (tmp != NULL)
	{
		if (tmp->zesp->is_double == 0)
			liczba->rzeczywista.a_double = liczba->rzeczywista.a_double + tmp->zesp->rzeczywista.a_int;
		else
			liczba->rzeczywista.a_double = liczba->rzeczywista.a_double + tmp->zesp->rzeczywista.a_double;
		liczba->uroj = liczba->uroj + tmp->zesp->uroj;
		tmp=tmp->next;
	}
	return liczba;
}

Zgaduję, że chodzi o to, że nie zwolniłem pamięci zajmowanej przez zmienną "liczba", jednak nie wiem, jak można to zrobić, gdyż wówczas tracę cały wynik funkcji. Da się coś z tym zrobić?

0

ta twoja struktura jest trochę WTF-owa, wiesz?

1

Jaki prowadzący, taka struktura, co poradzić, jest polecenie, trzeba wykonać ;)

0
void add(Container** glowa,L_zesp* zespol) {
        Container* e, *tmp;
 
     e = (Container*) malloc(sizeof(Container));     
     e->zesp=zespol;
 
     if (*glowa == NULL)     
      {
        /*e->next = *glowa;*/ // Sam na siebie ma pokazywać? Masz szczęście, że ustawiasz  "glowa" na NULL przed wywołaniem tej funkcji pierwszy raz.. ale ta linia to i tak błąd.
        e->next = NULL; // Tak powinno być
        *glowa = e;
      }
      else
       { 
         tmp = *glowa;
         while (tmp->next != NULL)
            tmp=tmp->next;          
            tmp->next = e;
            e->next = NULL; 
       }
}

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