Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[C] Dynamiczna alokacja pamięci.

<Pietrucha> 28 Dec 2004 01:00 3428 6
  • #1
    <Pietrucha>
    Level 2  
    Witam wszystkich.

    Otóż chce napisać taki programik, który wczytuje z pliku nazwiska ładuje je do zarezerwowanego obszaru pamięci (przy pomocy malloc). Z każdym nowym nazwiskiem chcę aby przypisany był wskaźnik do niego który przechowywany jest w dreugiej funkcji malloc. Jednak nie potrafię przypisać tego drugiego malloca do tego pierwszego tzn. tak żeby pierwszy z drugiego malloca wskazywał na pierwszy element w 1 mallocu (tam gdzie są nazwiska), 2 el. w 2 mall. wskazywał na 2 łańcuch znaków itd. Nie wiem czy dobrze kombinuję ale wydaje mi się że to powinno wyglądać tak: Najpierw przypisuję początkowe malloci potem wczytuje pierwszy napis do 1 malloca, zapamiętuję w 2 mallocu to położenie, wczytuję 3, i zapamiętuję to położenie. Jednak nie mam pojęcia jak zapamiętać te położenia. Mam nadzieję że nie zamieszałem za bardzo. Dziękuję za wszelkie opinie.

    Zamykam. - arnoldziq
  • #2
    shg
    Level 35  
    Hmmm, nie za bardzo kumam, ale co tam. :D

    Ja robię aktualnie coś takiego:

    Mam plik tekstowy, wczytuję go w całości, przeszukuję zawartość zamieniając znaki końca linii na NULL (zakończenie łańcucha) jednocześnie zliczając ilość linii, potem alokuję odpowiednią ilość pamięci (ilość linii * sizeof(char *) ), jeszcze raz przeszukuję plik i buduję tablice wskaźników na linie z tekstem. Też nieźle zamieszałem :D

    Dobra w skrócie:
    Ładuję cały plik na raz i tworzę tablicę zawierającą wskaźniki na każdą linię z załadowanego pliku tekstowego.

    malloc'a wstaw zamiast AllocMem(), tam masz jeszcze kilka funkcji z AmigaOS, ale raczej sobie poradzisz :D (komentarze po angielsku)
  • #3
    <Pietrucha>
    Level 2  
    A tak ygląda fragment programu:
    char *ppobierz;
    char *pwskaz;

    //maxline i lznakó są liczone wcześniej
    ppobierz=(char *) malloc(lznakow+maxline);
    pwskaz=(char *) malloc(maxline);

    if (ppobierz==NULL||pwskaz==NULL)
    {
    printf("Za malo pamieci aby wykonac zadanie");
    exit(2);
    }

    i=0;
    while (!feof(plik))
    {

    //chodzi mi o tę część programu, z tym że to co jest poniżej zapisane to przypisanie jednego wskaźnika do drugiego, tutaj jeszcze czegość brakuje do poprawnego działania, tylko nie wiem czego


    pwskaz=ppobierz;
    ppobierz=ppobierz+strelen(ppobierz);

    fgets(ppobierz,30,plik);

    }



    Czy mógłbyś zamieścić ten fragment kodu gdzie właśnie wczytujesz dane i przypisujesz linijkom wskaźniki??

    Wielkie dzięki za pomoc.
  • #4
    shg
    Level 35  
    <Pietrucha> wrote:
    Czy mógłbyś zamieścić ten fragment kodu gdzie właśnie wczytujesz dane i przypisujesz linijkom wskaźniki??


    No ten tego... yyyy... zamieściłem cały program, jedyne, co ten program robi, to wczytanie pliku tekstowego, i wyświetlenie jego zawartości, posprzątam trochę w kodzie i podpiszę to po polskiemu.

    Ten program jest tak napisany, żeby śmigał z prędkościa światla :D
    plik tekstowy 0.5 MB - 14474 linie ładuje się w niecałe 2 sekundy na komputerze z procesorem 14MHz. Word i Wordpad na komputere z zegarem 1GHz potrzebują na to około sekundy :)

    procedura prescan_buffer() wyszukuje nowe linie, i tworzy tabelę wskaźników
  • #5
    <Pietrucha>
    Level 2  
    No dobra wszystko fajnie ładuję sobie do malloca moje nazwiska no ale jak potem je wyciągnąć??. Nie potrafię przypisać wskaźnikowi miejsca rozpoczęcia się nazwiska. Porównanie jednego z drugim nic nie daje bo wtedy kopiuje jedno do drugiego a ja chcę aby tylko znał położenie w pamięci. Zapewne da się to zrobić w 1 linijce ale kurka wodna jak.
  • #6
    shg
    Level 35  
    hmmm, a mnie tu pokazuje, że nawet nie ściągnąłeś tego, co wrzuciłem, a tam jest napisane jak to zrobić.

    Napiszę jeszcze raz (osatni :D ):

    1. robisz malloca - rozmiar pamięci o 1 większy niż cały plik, tablica przypisana do wskaźnika na char, czyli deklaracja: char *plik;
    2. ładujesz do tego obszaru swój plik.
    /* Teraz w zależności od tego, jak są zorganizowane dane w Twoim pliku - jak masz jedno nazwisko = 1 linia, to na końcu zaalokowanego obszaru zapisujesz znk końca linii (0x0a) i: */
    3.1 zamieniasz wszystkie znaki końca linii (kody 0x0d, 0x0a w wersji PC, albo tylko 0x0a w wersji amigowej) na znaki końca łańcucha (liczbowo: NULL :D)
    /* jak masz nazwiska oddzielone spacjami, to na końcu zaalokowanego obszaru zapisujesz spację i:*/
    3.2 zamieniasz wszystkie spacje (kod 0x20) na znaki końca łańcucha (liczbowo: NULL :D)

    3.3 przy każdej zamianie kodów zliczasz sobie jedną linię.

    4. Następny malloc, tym razem rozmiar o wielkości (sizeof(char *) * (ilość linii)) i to będzie Twoja tablica wskaźników na linie, czyli deklaracja tej zmiennej: char **linie;
    5. na pierwszą pozycję w tabeli linii wstawiasz początek pliku, czyli: *line[0] = plik;, albo tak jak ja to robię *line++ = plik;, co automatycznie przesuwa mi wskaźnik na następną pozycję w tablicy.

    6. w pętli przeszukujesz cały załadowany plik, czyli odczytujesz, to na co wskazuje wskaźnik plik a potem go zwiększasz
    7. jeżeli wskazywał na NULL, to to, na co wskazuje teraz jest następną linią, czyli robisz *line++ = plik
    8. kroki 6. i 7. powtarzasz tak długo, aż przetworzysz tyle bajtów ile załadowałeś, albo tyle linii, ile naliczyłeś
  • #7
    <Pietrucha>
    Level 2  
    Wielkie dzięki, a co do ściągania to poprostu jakoś tego nie zauważyłem. Logowałem się tylko wtedy gdy chciałem napisać posta i stąd moje zamieszanie. Teraz już wszystko jasne i poszło.
    Wielkie dzięki za cierpliwość i za poświęcony czas.