Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 23 sty 2026, o 08:19


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 
Autor Wiadomość
PostNapisane: 9 sie 2014, o 21:38 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Dajmy na to, że mam taki kod:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Pytanie brzmi: czy y == wsk? Chodzi o to, czy wartość zwracana przez funkcję (czyli moje x, lokalne) jest tą samą komórką w pamięci co zmienna do której wrzucam wynik, czyli z.

Po co mi to? Załóżmy, że w funkcji tworzę sobie jakąś zmienną, tworzę wskaźnik na nią i chcę go zapisać w jakiejś globalnej tablicy wskaźników a następnie ją zwrócić i móc potem ją odczytywać korzystając z mojej tablicy ze wskaźnikami. Wiem, że można użyć malloc i zwracać wskaźnik, ale jestem ciekaw jak są zwracane wartości przez funkcję. Podejrzałem kod assemblera wygenerowany z tego przykładu, ale jestem za cienki w asm żeby odpowiedzieć sobie samemu. Wygląda to tak:

Składnia: [ Pobierz ] [ Ukryj ]
język asm
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sie 2014, o 21:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Tworząc taką zmienną w funkcji to tylko w jej zasięgu będzie ona widoczna. Zwracanie wskaźnika na taką zmienną może dać nieoczekiwane rezultaty przy jego wykorzystaniu, ponieważ po utraceniu zasięgu jest ona niszczona i jako już wolna komórka pamięci może ona zostać użyta przez program w dowolny sposób. Wobec czego bez Twojej wiedzy wartość 16 może ulec zmianie...

Co to pytania czy "y == wsk" to odpowiedź brzmi "nie". Dlatego że do zmiennej wskaźnikowej "y" zapisywany jest adres zmiennej "z" a nie "x". Funkcja musiałaby zwracać wskaźnik na "x", co jest zdecydowanie nie wskazane.

Rozwiązaniem tych problemów w C++ są referencje, ale i w C można sobie całkiem nieźle poradzić używając wskaźników tzn. w głównej funkcji "main" alokowana jest pamięć, która nie zostanie nigdy automatycznie zwolniona, a następnie adres tego miejsca w pamięci przekazywany jest do funkcji, która ma na tych komórkach dokonywać operacji. Tym sposobem wskazanie jest cały czas poprawne (w przypadku tworzenia zmiennych na stosie, adres również jest poprawny, ale dane mogą ulec zmianie) oraz dane pozostają niezmienne (stos nie ma wpływu na młodsze adresowo komórki RAM.



Ostatnio edytowano 9 sie 2014, o 21:57 przez atmel, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sie 2014, o 21:56 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Czyli tak jak myślałem. Można to jakoś zrobić bez użycia malloca i zwracania wskaźnika? Chodzi o to żeby funkcja tworzyła zmienną i jednocześnie zapisywała gdzieś wskaźnik do niej.

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 9 sie 2014, o 22:07 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 07 kwi 2013
Posty: 418
Lokalizacja: Rzeszów
Pomógł: 102

Nie wiem czy dobrze myślę, ale jest też na to inny sposób, prócz statycznych tablic oczywiście.

Można utworzyć wskaźnik w obszarze zmiennych globalnych na pewne miejsce w pamięci (zaalokować wstępnie 1 bajt pamięci dla uzyskania adresu). Następnie we własnej funkcji można użyć funkcji "realloc", która powiększy ten obszar pamięci o konkretną wartość. Dzięki temu uzyskujemy poprawne wskazanie oraz niezmienne dane niezależne od miejsca ich lokowania. Zwracany wskaźnik w tym przypadku będzie poprawny i myślę, że ma to szanse działać :)

Zamieszczam przykładowy kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Można zmodyfikować funkcje tak, aby mogły pobierać jako parametr dowolny adres w pamięci (może być to również zmienna lokalna dla funkcji "main"), a następnie powiększać go o 1 bajt. Zakładam tutaj że funkcja "malloc" oraz "realloc" automatycznie zeruje nowoutworzone komórki pamięci. W przeciwnym razie trzeba im przypisać wartość 0, albo użyć funkcji "memset" dla większych bloków alokowanej pamięci.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 10 sie 2014, o 09:29 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 18 maja 2014
Posty: 126
Pomógł: 12

Tak właśnie robię, byłem ciekaw czy można inaczej do tego podejść.

_________________
Pozdrawiam, Adrian.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 3 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO