dlaczego ** a nie *

0

Witam, mam pytanie programu napisanego w c mam problem z dodawaniem elementu do listy
Moj program wyglada mniej wiecej tak:
#include <stdio.h>
#include <stdlib.h>
#include<stddef.h>

typedef struct element{
struct element next;
int val;
}el_listy;
void dodajDoListy(el_listy head,int val){
el_listy
wsk;
if(head==NULL){
wsk=(el_listy
)malloc(sizeof(el_listy));
wsk->val=val;
head=wsk;
}else{
......................
}
}
int main(int argc,char **argv)
{
el_listy *head=NULL;
dodajDoListy(head,123);
return 0;
}
dlaczego przy próbie dodania pierwszego elementu program mi sie zawiesza ??
i dlaczego taka wersja programu dziala normalnie
.........
typedef struct element{
struct element *next;
int val;
}el_listy;
void dodajDoListy(el_listy *head,int val){
el_listy
wsk;
if(head==NULL){
wsk=(el_listy
)malloc(sizeof(el_listy));
wsk->val=val;
*head=wsk;
}else{
......................
}
}
int main(int argc,char **argv)
{
el_listy *head=NULL;
dodajDoListy(&head,123);
return 0;
}

0

Czy on wywala się w tej postaci, co podaleś, czy może w jakiejś części, którą usunąłeś w tym poście?
Chodzi o to, że obie wersje moim zdaniem nie powinny się zawieszać. Różnica jest jedynie w tym, czy pobierasz wskaźnik do "head" czy wskaźnik do wskaźnika do "head". Czy nie jest tak, że zawiesza się np. dopiero przy którymś wstawianiu kolejnego elementu?

No i tak przy okazji: co udało ci się samemu znaleźć pod debugerem? Masz jakiś podejrzany fragment kodu?

0

wywala sie wtedy jak odwoluje sie do dodanego elementu
wywolanie instrukcji printf("%d",head->val); wywala mi program i nie wiem czemu
z tego co wybadalem to przekazywanie do funkcji wskaznikow NULL nie dziala do konca tak jak powinno
ale nie wiem czemu??
Ponizej podalem konkretny przyklad przy ktorym sypie sie program

#include <stdio.h>
#include <stdlib.h>
typedef struct element{
struct element *next;
int val;
}el_listy;

void insertAtEnd(el_listy* head,int val){
el_listy current,newNode;
if(head==NULL){
current=(el_listy
)malloc(sizeof(el_listy));
current->val=val;
current->next=NULL;
head=current;
}else{
current=head;
while(current->next!=NULL){
current=current->next;
}
newNode=(el_listy
)malloc(sizeof(el_listy));
newNode->next=NULL;
newNode->val=val;
current->next=newNode;

}

}

int main()
{
el_listy* head=NULL;
insertAtEnd(head,123);
printf("%d",head->val);
return 0;
}

0

int main()
{
el_listy* head=NULL;
insertAtEnd(head,123);
printf("%d",head->val);
return 0;
}

Jeśli insertAtEnd() pobiera jako parametr "head", to tworzy jego kopię i wewnątrz tej funkcji inicjuje ją za pomocą malloc(). Ale po wyjściu z funkcji, gdy wracasz do "main(), wskaźnik "head" w main wciąż ma wartość NULL. Czyli błąd powstaje dla deklaracji "void insertAtEnd(el_listy* head, int val)".

Gdy zmienimy deklarację i definicję funkcji na "void insertAtEnd(el_listy** head, int val)" to wtedy "head" z main zostaje zmodyfikowany, czyli wskazuje na obszar pamięci zaalokowany w funkcji InsertAtEnd(), więc się nie wywala.

0

ale z tego co wiem to to jest przekazywanie przez wskaźnik i że przekazuje adres zmiennej i że zmiany powinny być widoczne po zakończeniu funkcji

0

jeśli zmienna zostanie zainicjowana normalnie to wtedy nie ma problemu zmienna zostaje zmieniona ale z NULL już tak nie działa

0

ale w pierwszym przypadku zmienna el_listy* head jest kopią wskaźnika z maina. Czyli jak przypiszesz jej jakąś wartość, to i tak przestaje ona istnieć po wyjściu w funkcji InsertAtEnd().
To tak jakbyś zrobił:

void func(int x)
{
x++;
}

int main()
{
int val = 0;
func(val);
printf("%d", val);
return 0;
}

printf() wypisze ci, że val =0, a nie 1, bo func operuje nie na oryginalnej wartości, tylko na swojej kopii. To samo jest jesli zmienna jest wskaźnikiem.Operujesz na kpiii wskaźnika i cokolwiek z nim zrobisz wewnątrz funckji, to po wyjściu z niej ta kopia jej niszczona.

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