Polibuda napisał(a)
Kumashi poczekaj ,bo mi namieszałeś jak piekło teraz wcześniejszą wypowiedzią:D
Nie umieściłem jako kod ,bo zwyczajnie nie wiem jak to zrobić ,a potrzebowałem w miarę szybkiej odpowiedzi.
Umieść kod w znacznikach code
, np.
<code class="c">int main(void);</code>
Polibuda napisał(a)
Niespójność nazw wynika z tego ,że gdybym chciał zrobić zmienna size to na 99% kolidowała ,by z jakaś funkcja z biblioteki (chyba miałem kiedyś problem z tą nazwą i dlatego czasami tylko dodaje _ a czasami używam polskich nazw (Jedynie w programach na zajęcia ,gdyż są na tyle małe ,że jestem w stanie je spamiętać.
Nie ma konfliktu nazw w bibliotece standardowej z size
, length
, str_size
czy str_length
. Możesz też stosować nazwy skrócone (len
) czy różnego rodzaju prefiksy i sufiksy. Jeśli chcesz uniknąć konfliktów w dół w przypadku nazw funkcji, deklaruj je jako static.
Jak chcesz, to nazywaj je po polsku, ale niech to będzie spójne, a nie robisz z kodu Esperanto. To naprawdę utrudnia czytanie, o pisaniu nie wspominając. A nazwy zapamiętasz przez miesiąc, może dwa. Programy na zajęcia musi czytać Twój wykładowca, miej dla niego litość.
Polibuda napisał(a)
właśnie dlatego napisałem funkcję z parametrem int określającym rozmiar żeby ,był zawsze dodatni:)
Typ int
to jest liczba całkowita ze znakiem. Zapewne chodziło Ci o ''unsigned int'.
Polibuda napisał(a)
Nie uważam tego za bezsensowne. Przepisuje sobie wartość do lokalnego wskaźnika ,który na chwile ma przydzieloną pamięć mogącą pomieścić dany string.
Po co? Przecież te dane masz już w pamięci. Nikt Ci ich nie ukradnie w środku funkcji. Niepotrzebnie kopiujesz dane, a dla wykładowcy to może wyglądać jak brak znajomości działania wskaźników.
Polibuda napisał(a)
Z zasady Każdą dynamiczne alokowaną pamięć trzeba zwolnić bo jeśli się tego nie zrobi. to straci się adres pamięci gdzie ta zarezerwowana pamięć jest. Ja to rozumiem tak że pamięć dalej będzie zajęta przez pewne składniki dane (i nie będzie mogła być nadpisana) ,ale my utracimy do niej możliwość dostępu. (może rozumuję źle) następnie alokuję nową pamięć odpowiednio powiększoną zapisuję jej adres do starego wskaźnika i i przepisuje do niego starą wartość wyrażenia po czym zwalniam pamięć zajmowaną przez wskaźnik tymczasowy. Ponieważ funkcja odbierała wskaźnik to znaczy że w trakcie pracy funkcji modyfikowała wartość oryginalnego wskaźnika i teraz on ma tą powiększoną wartość.
Ale Ty modyfikujesz tylko lokalną kopię wskaźnika. Żeby zmodyfikować wskaźnik, musisz do funkcji przekazać wskaźnik na wskaźnik. Przy czym funkcja free()
ma gdzieś czy Ty jej przekazujesz kopię lokalną czy nie i zwalnia obszar, do którego adres masz zapisany we wskaźniku. W efekcie dealokujesz pamięć, a wartość wskaźnika poza funkcją pozostaje bez zmian, zatem wskazuje on na zdealokowaną przestrzeń, lub zaalokowaną już pod inne dane. Ponadto, adres do nowozaalokowanej przestrzeni masz tylko w kopii lokalnej, do której tracisz dostęp po wyjściu z funkcji i masz dokładnie to, o czym piszesz na początku powyższego cytatu.
Polibuda napisał(a)
I to działa problem w tym że do drugiego obiegu pętli.
To Ci działa, gdyż po zdealokowaniu pamięć nie jest czyszczona i dalej możesz się do tych danych dobrać przez stary adres, tyle że nie powinieneś. Tutaj masz główny błąd i dalsze dywagacje na temat działania nie mają sensu, gdyż masz zwalone dane. Program może się zachowywać w sposób nieprzewidywalny, zawieszać się, wysypywać z błędem, generować błędne wyniki, uśmiercić chomika, ...
Polibuda napisał(a)
mógłbym to zrobić tak jak proponujesz ale nie w funkcji. Dlaczego? bo musiał bym zwrócić adres tego nowego wskaźnika a to oznacza że nie mógłbym zwolnić przydzielonej mu pamięci ,aż do instrukcji return ,a umieszczanie jej po returnie nie miało by już sensu. chyba że ja naprawdę czegoś nie rozumiem.
Nie rozumiesz. Zwalniasz tylko "starą" przestrzeń, a wskaźnik do nowej zwracasz lub zapisujesz pod w "starym" miejscu (jeśli funkcja będzie przyjmowała wskaźnik na wskaźnik). I nie musisz robić rzeźby z dwiema alokacjami. Spróbuj pokombinować sam, a jak Ci nie będzie szło, daj znać. Napiszę Ci oba warianty.
Polibuda napisał(a)
bilbosz musi być funkcja... program nie polega na takiej alokacji tylko na pobraniu imienia i nazwiska użytkownika (a potem kilka innych zadań też z wczytywaniem) ale alokowanie dwóch tablic o rozmiarze powiedzmy po 50 elementów każda i wczytywanie wartości do niej byłoby zbyt proste i nic by mnie nie nauczyło to umiem od dawna... chcę sięgnąć wyżej zrobić coś więcej niż to co wymagane:D
No to jak chcesz wyzwania, to zrób to na liście powiązanej i "kompiluj" ciąg wynikowy po pobraniu wszystkich danych ;)