Zmiana adresu, wkazywanego przez wskaźnik, w funkcji [C]

0

Mam problem, gdyż próbuję zmienić adres przypisany do wskaźnika w funkcji i to dzieje się poprawnie, jednak po wyjściu z funkcji wartość ta zostaje usuwana.

Kody:

1:

Stos *obecny=NULL;
Stos *element;

2: element=dodaj_element(obecny,znak);

3:

Stos *dodaj_element(Stos *obecny, char znak){
	Stos *dodaj=NULL;

	dodaj=(Stos*)malloc(sizeof(Stos));
	
	if(obecny==NULL){
		obecny=dodaj;
		dodaj->prev=NULL;
		(*dodaj).znak=znak;
	}
	else{
		dodaj->prev=obecny;
		dodaj->znak=znak;
		obecny=dodaj;
	}
	return dodaj;
}
1

Nie ma w tym nic dziwnego, kopiujesz wskaźnik jako wartość. Przekaż wskaźnik do wskaźnika.

0

A nie prawda, bo jak sprawdzam po przypisaniu obecny=dodaj; printf-em, to wskazuje dokładnie adres dodaj.

0

Naprawdę? (ps: "nieprawda" ⟶ łącznie)

http://melpon.org/wandbox/permlink/rfaE9Um7nS9i9ZoE

9

@PianistaMichal musisz zaczać odróżnicać adres na który pokazuje wskaźnik od adresu gdzie w pamięci znajduje się ten wskaźnik. Przekazujac do funkcji argument robisz jego kopię. W przypadku wskaźnika jest to oczywiście kopia wskaźnika a nie obiektu na który on pokazuje. W efekcie masz tak na prawdę dwa wskaźniki pokazujące na to samo. Zmiana wartości jednego z nich (czyli zmiana tego na co on pokazuje) NIE spowoduje że ten drugi nagle zacznie wskazywać na coś innego.
Analogia:
Masz numer telefonu do swietnej dziewczyny zapisany na kartce. Kartka to wskaźnik, dziewczyna to obiekt na który on pokazuje. Twój kolega chce do tej dziewczyny uderzać więc przepisujesz mu numer telefonu na nową kartę i dajesz (wywołanie funkcji). Dziewczyna zmieniła numer więc kolega zmazał numer na swojej kartce i zapisał nowy (przypisanie nowego obiektu do wskaźnika w funkcji). Czy to sprawiło nagle, że numer zapisany na kartce, którą ty masz się zmienił? Raczej nie :)
Co można więc zrobić? Możesz powiedzieć koledze: "numer dziewczyny jest na kartce w szufladzie" (czyli mówisz mu gdzie znajduje się wskaźnik, a nie na co on pokazuje -> przekazujesz wskaźnik do wskaźnika). Teraz jeśli dziewczyna zmieni numer to kolega może iść do szuflady, wyjąć oryginalną kartę i zmienić numer.

2
Stos *dodaj_element(Stos **obecny, char znak){
    Stos *dodaj=(Stos*)malloc(sizeof(Stos));
    if (dodaj) {
        dodaj->prev=*obecny;
        *obecny = dodaj;
        dodaj->znak=znak;
    }
    return dodaj;
}

element=dodaj_element(&obecny,znak); 
0

Dzięki panowie. Jest dokładnie tak jak mówicie, wszystko teraz działa tak jak należy. A i wyjaśnienie problemu jest wyczerpujące.

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