Listy dwukierunkowe, dynamiczna rezerwacja pamięci do klucza

0

Witam!
Mam pytanie odnośnie list dwukierunkowych, starałem się wymyślić jak zrobić aby dynamicznie alokować pamięć do wskaźnika typu char w strukturze ( chodzi o wartość klucza key). Napisałem program , natomiast mam 3 pytania:

  1. czy muszę za każdym razem pytać o długość wprowadzonego klucza? Jest to dość męczące..
  2. Dlaczego program działa tylko 2x. Za trzecim razem się kończy?
  3. Jest jakiś inny sposób aby rozwiązać ten problem? pewnie deklaracja z góry w strukturze np.char ch[10]. Ale mi zależy na dynamicznej alokacji.
 #include <stdio.h>
#include <stdlib.h>

struct element {
	char *key;
	struct element *next;
	struct element *prev;
};

struct element *lista_odwroc(struct element *head);
struct element *lista_dodaj(struct element *head, struct element *nowy);
struct element *funkcja_napisz(struct element *head,char *ch);
void lista_wypisz(struct element *head);

int main (void)
{
	struct element *head=NULL, *nowy=NULL;
	char z,*ch;
	int x;

	
	

	while(1)
	{
		printf("Co chcesz zrobic?\n");
		printf("d-dodaj element na koniec\n");
		printf("w-wypisz liste\n");
		printf("q-wyjdz\n************************\n");

		fflush(stdin);
		z=getchar();

		switch(z)
		{

		case 'd':	
					printf("Podaj dlugosc klucza: ");
					scanf("%d",&x);
					printf("Podaj wartosc klucza: ");
					fflush(stdin);
					ch=(char *)malloc((x+1)*sizeof(char));
					gets(ch);
					head=funkcja_napisz(head,ch);
					break;

		case 'w':	lista_wypisz(head);
					break;

		case 'q':  return 0;

					
		}
	}
}
struct element *lista_odwroc(struct element *head)
{
	struct element *inverted=NULL;
	struct element *x=head;
	struct element *y=NULL;

	while(x != NULL)
	{
		y=x->next;
		inverted=lista_dodaj(inverted,x);
		x=y;

	}
	free(head);
	return inverted;
}
struct element *lista_dodaj(struct element *head, struct element *nowy)
{
        nowy->prev=NULL;
        nowy->next=head;
       
        if(head != NULL)
                head->prev=nowy;
       
        head=nowy;
        return head;
}
void lista_wypisz(struct element *head)
{
		struct element *x = head;
 
        while (x != NULL)
           {
             printf("%s ", x->key);
             x = x->next;
           }
}
struct element *funkcja_napisz(struct element *head,char *ch)
{
	struct element *nowy=(struct element *)malloc(sizeof(struct element));
	int dlugosc=0;
	int k;

	for(k=0;*(ch+k) != '\0' ; k++)
		dlugosc++;

	nowy->key=(char *)malloc(dlugosc);
	nowy->key=ch;

	if(head != NULL)
	{
		head=lista_odwroc(head);
		head=lista_dodaj(head,nowy);
		head=lista_odwroc(head);
	}
	else
		head=lista_dodaj(head,nowy);

	return head;
	
}
0

dziękuje za szybką odpowiedź zaraz poczytam o tej funkcji , jeżeli będę miał jakieś pytania napiszę :) raczej w gre wchodzi pisanie wszystkiego samemu - taki wykladowca :D

0

Poprawiłem program z funkcja strdup() odpada pytanie nr 3, odpada pytanie nr. 2 winna byla instrukcja free(head) w funkcji lista_odwroc(). Zostaje pytanie nr.1 czy muszę za każdym razem "..." ? I dlaczego źle zwalniam pamięć , przecież tworze nową głowę listy (inverted).

0

Przepraszam za post pod postem , nie moge edytowac. free(x) <- działa poprawnie. Zostaje pytanie 1 :)

0

Ja bym to zrobil w starym dobrym stylu ;)

char buffer[1024];
scanf("%1023s", buffer);

Mozesz tez zrobic bufor tymczasowy, wczytywac do tego bufora, a potem kopiowac do wlasciwego [brzydko]

Mozesz tez zaimplementowac dynamiczny kontener typu std::vector<>, dla ulatwienia dla jednego typu co nie jest takie trudne.

0
n0name_l napisał(a):

Ja bym to zrobil w starym dobrym stylu ;)

char buffer[1024];
scanf("%1023s", buffer);

Kurcze fajna sprawa wszystko smiga !
Tylko na jakiej zasadzie działa "1023"? i Czy to też jest "brzydko" ? :P

0

%1023s ogranicza ilość wprowadzonych znaków do 1023 (bufor ma 1024, ponieważ musi zmieścić się jeszcze null-terminator).
Jest o tym napisane w dokumentacji, gdzie powinieneś był zajrzeć.

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