Lista jednokierunkowa

0

Witam.

Pracuję nad listą jednokierunkową. Mam spory problem aby zrozumieć jak przekazać łańcuch znaków do elementu listy. Zapisując listę, za pomocą wskaźnika, losowo generowanymi danymi okazuje się, że wszystkie dane mają wartość ostatniego wylosowanego elementu. Przy przesyłaniu "gotowego" łańcucha nie ma takiego problemu.Czy ktoś wie dlaczego tak się dziej i jak to poprawić.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct node {
    int a;
    char *b;
    struct node * next;
} list;

list* createList(){
    list * head = NULL;
	head = malloc(sizeof(list));
    return NULL;
}
list *insert(list **head, int _a, char *_b){
    list * temp;
    temp = malloc(sizeof(list));
    temp->a = _a;
    temp->b = _b;
    temp->next = *head;
    *head = temp;
}

void showList(list * head){
    list * temp = head;
    if(temp == NULL)
        printf("Empty \n");
    while (temp != NULL) {
        printf("%d  %s",temp->a, temp->b);
        printf("\n--------------------------------------------------------\n");
        temp = temp->next;
    }
}
int main (){
    time_t czas,start=time(NULL);
    time(&czas);
    srand(time(&czas));
    int a=0,cnt=0;
    char b[4];
    list *list;
	list = createList();

    while(cnt<10){
        a=( rand()%70+50);
        for(int i=0;i<3;i++)
            b[i]=(rand()%26+65);
        cnt++;
        insert(&list,a,b);
        printf("b = %s \n",b);//wyswietla dobrze
    }
    printf("Podaj 3 znaki \n");
    scanf("%s",b);
    insert(&list,1,b);
    showList(list);//zamienia szystko na aktualne b

    printf("Podaj 3 znaki \n");
    scanf("%s",b);
    insert(&list,2,b);
    insert(&list,3,"dziala");//w ten sposob dziala
    showList(list);// ostatnia wartosc b jest przypisana do wszystkich elementow listy
    return 0;
}

1

Mam spory problem aby zrozumieć jak przekazać łańcuch znaków do elementu listy

Lista jednokierunkowa [C]

0

Nic mi to nie tłumaczy. Bazując na tym przykładzie uzyskałem ten sam efekt. Nie rozumiem gdzie jest błąd. Jeżeli zarezerwuję pamięć to wszystko ok ale po zwolnieniu pamięci we wszystkich elementach listy występuje jedna losowa wartość. Ta sama we wszystkich.

2

Jeżeli zarezerwuję pamięć to wszystko ok ale po zwolnieniu pamięci we wszystkich elementach listy występuje jedna losowa wartość

Nie wiem jaki masz problem, bo opisałeś tutaj poprawne zachowanie. Napis w C to po prostu tablica znaków i musisz dla niego zarezerwować pamięć. Wyjątkiem są literały, które są przetrzymywane na stałe w binarce i nie musisz dla nich nic rezerwować, z tymże nie możesz też ich modyfikować.

Jeżeli swój node definiujesz tak:

typedef struct node {
    int a;
    char *b;
    struct node * next;
} list;

to znaczy, że lista jako taka nie przechowuje napisu tylko wskaźnik do niego. Dlatego podesłałem Ci przykład listy, która rezerwuje pamięć na swoje potrzeby.

0

Ok, dzięki.
Czyli chciałem umieścić we wskaźniku napis. Trochę ciężko :)
Moja pętla przypisuje ten sam wskaźnik do każdego elementu listy i dlatego wszystkie mają wartość ostatniego elementu?

typedef struct node {
    int a;
    char b[4];
    struct node * next;
} list;

Czyli takie coś powinno mi rozwiązać problem?

1

Moja pętla przypisuje ten sam wskaźnik do każdego elementu listy i dlatego wszystkie mają wartość ostatniego elementu?

Dokładnie tak. Dlatego też po zwolnieniu pamięci miałeś tą samą "wartość" wszędzie. Każdy wskaźnik pokazywał na ten sam fragment nie zaalokowanej pamięci.

Czyli takie coś powinno mi rozwiązać problem?

Tak, jeśli chcesz przechowywać napis złożony z czterech znaków, to trochę niewiele ;) Musisz dodatkowo zmodyfikować kopiowanie napisu, w tym miejscu:

temp->b = _b;

Powyższy zapis skopiuje wskaźnik. Użyj funkcji strcpy. Pamiętaj tylko o nullu na końcu napisu.

1

Ok. Już rozumiem gdzie leżał błąd w moim rozumowaniu. Dzięki.
Wątek można chyba zamknąć.

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