• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Proszę o wyjaśnienie : tablica wskaźników , odczyt z pliku, malloc().

VPS Starter Arubacloud
0 głosów
959 wizyt
pytanie zadane 8 lutego 2017 w C i C++ przez maciekkov Początkujący (360 p.)

Witam

Próbuję odczytać dane z pliku i umieścić je w buforze. Zamiast tworzyć 30 tablic chcę stworzyć tablice wskaźników aby tam umieścić wskaźniki do poszczególnych stringów. A więc w main() zadeklarowałem pamięć

 char **bufor=(char**)malloc(30 * sizeof(char));
    for(i=0;i<30;i++){
        bufor[i]=(char*)malloc(300 * sizeof(char));
    }

1)Proszę mnie poprawić ale jeśli dobrze rozumuję zrobiłem coś następującego. 
Zadeklarowałem wskaźnik , który określa początek miejsca w pamięci gdzie kolejno będzie utworzonych 30 wskaźników do zmiennej typu char. Następnie dla każdego wskaźnika przypisałem pamięć 300 "pól" z czego każde pole jest wielkości char. Tak?

2)Czy powyższy zapis jest równoważny  z tym zapisem jeśli zdefiniujemy tą tablicę jako zmienną globalną i zostanie ona z racji tego zainicjowana  zerami?    char*bufor[30]; 

 

3) Funkcję wczytująca dane z pliku wywołałem w ten sposób      read(bufor)

    a zdefiniowałem następująco       void read(char**buf)

Czy to znaczy że wysłałem do funkcji jako argument wskaźnik do wskaźników na char?

 

4)Następnie przy użyciu poniższego kodu próbuję pobrać kolejne linie i zapisać je w pamięci.

i=0;
while( (fgets(buf[i],350,plik))!=NULL){
       
        puts(buf[i]);
        i++;
}

Nie chce działać. Kiedy w main() próbuję wyświetlić zawartość char**bufor są tam same śmieci i w połowie program się wysypuje.
CO ciekawe gdy używam lokalnej zwykłej tablicy wszystko działa. Na przykład :

char lokalny[1000]; 
while( (fgets(lokalny,350,plik))!=NULL){
        puts(lokalny);

}

Prosiłbym o pomoc w rozwiązaniu tego i napisanie czy dobrze rozumuje powyższe zagadnienia.

1 odpowiedź

+2 głosów
odpowiedź 8 lutego 2017 przez Patrycjerz Mędrzec (192,340 p.)
wybrane 8 lutego 2017 przez maciekkov
 
Najlepsza
  1. Tak.
  2. W pierwszym zapisie deklarujesz 30 tablic o wielkości 300 znaków (bajtów), zaś w drugim jedynie 30 wskaźników, a przecież sam wskaźnik nie jest tablicą. Oczywiście dane w tablicy globalnej zostaną wyzerowane, jak słusznie zauważyłeś, ale tablice zaalokowane dynamicznie nadal będą zawierać śmieci. Aby je wyzerować, należy użyć funkcję calloc.
  3. Konkretnie wysłałeś wskaźnik na wskaźnik na char. Do reszty elementów tablicy odwołujesz się poprzez arytmetykę wskaźników.
  4. W pierwszym wywołaniu fgets czytasz 350 znaków, a tablica ma rozmiar 299 + 1 (jedynka dla nulla), więc to nie ma prawa działać. W drugim zaś tablica posiada odpowiedni rozmiar, aby pomieścić wszelkie dane, ale za każdym razem są one nadpisywane przez nowe, więc ten zapis, oprócz do wypisywania w locie danych, nie ma większego sensu.
komentarz 8 lutego 2017 przez Patrycjerz Mędrzec (192,340 p.)
Mam rozumieć, że w menu najpierw wywołujesz funkcję czwartą, a potem pierwszą?
komentarz 8 lutego 2017 przez maciekkov Początkujący (360 p.)
Jeśli nie masz tego pliku to generujesz sobie nowy, A jeśli chcesz odczytywać obecnie utworzony to wciskasz bezpośrednio 1. Program będzie rozbudowany o szukanie poszczególnych rekordów po nazwie bądź po numerze, wyświetlania listy całych bądź kilku rekordów. Ale stanąłem bo nie działą mi bufor który jest potrzebny do wszystkiego.

 

Ogólnie to zadanie zadał mi mój kolega i jest to jak się domyślam część większego zadania dla mnie .Gość pracuje w branży kupę lat i testuje w ten sposób moją wiedzę.

 

A jak widać moja wiedza kończy się w 10 rekordzie :D hehehe
1
komentarz 8 lutego 2017 przez Patrycjerz Mędrzec (192,340 p.)

Zauważ, że wskaźnik nie waży jeden bajt, ale w systemie 32-bitowym cztery bajty, a w 64-bitowym osiem, więc przy alokacji tablicy wskaźników powinieneś użyć sizeof(char*), nie zaś sizeof(char). Tzn. zmieniasz wywołanie sizeof jedynie pierwsze, w pętli wszystko zostaje jak było. No i zwolnienie tablicy dwuwymiarowej nie odbywa się przez free(bufor), ale zwalniasz ją odwrotnie do jej alokacji, najpierw tablice znaków (w pętli), potem tablica wskaźników.

komentarz 8 lutego 2017 przez maciekkov Początkujący (360 p.)
Działa jak należy :) Dziękuję bardzo za wyjaśnienie. Wstawić gwiazdkę to każdy tam sobie mógł na chybił trafił  ale żeby wytłumaczyć dlaczego to już nie każdy... Widzę, że wielka wiedza się kłania :) Pozdrawiam.
komentarz 8 lutego 2017 przez Patrycjerz Mędrzec (192,340 p.)
Dziękuję za pochwały, ale jakby nie patrzeć, jest to elementarna wiedza na temat wskaźników i dynamicznej alokacji pamięci, więc trudno, abym jej nie znał.

Jeślibyś jeszcze czegoś nie rozumiał, pytaj śmiało, nawet na wiadomość prywatną.

Podobne pytania

0 głosów
1 odpowiedź 318 wizyt
pytanie zadane 25 sierpnia 2020 w C i C++ przez fortuna Początkujący (310 p.)
0 głosów
0 odpowiedzi 121 wizyt
0 głosów
1 odpowiedź 416 wizyt
pytanie zadane 27 stycznia 2018 w C i C++ przez RedRevenge Obywatel (1,230 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...