GRY-Online.pl --> Archiwum Forum

C (raczej nie ++) i dynamiczne alokowanie pamieci oraz aktualizacja plikow - HELP

20.04.2002
18:28
smile
[1]

Theddas [ Konsul ]

C (raczej nie ++) i dynamiczne alokowanie pamieci oraz aktualizacja plikow - HELP

Witam

Bladzac od czasu do czasu po tym forum zauwazylem, ze sporo tu osob zna sie (lub sprawia takie wrazenie :)) na C i pochodnych (C++, Visual, etc.). W zwiazku z tym, ze poswiecilem juz mojemu problemowi sporo czasu postanowilem zapytac rowniez tutaj, a nuz ktos mi pomoze :).

Oba problemy oczywiscie maja zwiazek z programowaniem w C.

1. Dynamiczne alokowanie pamieci.
Jak wiadomo sluza do tego malloc() i calloc (new() narazie nie wchodzi w gre). Wszystko ladnie i cacy, tworze sobie listy, drzewka itd. Ale... mam problemy z pamiecia. Korzystam z Borlanda 3.1, ustawilem memory model na huge (najwiekszy), ale to nic nie zmienia. Dostepnej pamieci przy korzystaniu jest okolo 62kb, tyle pokazuje przynajmniej funkcja coreleft(). Zmniejsza sie ona bardzo szybko (pisze pamieciozerny program ;) az wreszcie zaczyna jej brakowac. Domyslam sie w tym momencie, ze powinienem skorzystac z nastepnego dostepnego segmentu pamieci, ktore jak wiadomo maja wielkosci ~64kb. Pytanie brzmi: jak to zrobic? Jak sprawic, by malloc() wzglednie calloc() potrafily rezerwowac kolejne miejsca w pamieci dla nastepnego (-ych) segmentow? Od biedy te 640kb konwencjonalnej by mi juz starczylo, ale 64kb to stanowczo za malo :(. Jezeli ktos chce mi pomoc, zna sie na rzeczy, ale nie do konca zrozumial o co mi chodzi, to moge wyjasnic dokladnie i zaaplikowac jakis przyklad, ale to jak bedzie potrzebne.

2. Aktualizacja plikow.
Problem jest trywialny (takie sprawia wrazenie ;), ale dla mnie nierozwiazywalny poki co w jakis prosty sposob. Chodzi mianowicie o to jak zaktualizowac plik (binarny w domysle). Przykladowo niech nasz plik sklada sie z szeregu zapisanych do niego struktur danych, kazda po 100 bajtow. Bez problemu moge do niego dopisywac nowe dane na koniec, nowe dane miedzy jedna struktura a druga, odczytywac je jak chce (fread, fwrite), przechodzic do danego miejsca (fseek), badac miejsce struktury w pliku (fteel) itd. etc. ale... chce plik zaktualizowac, a tego juz w prosty sposob chyba sie zrobic nie da (?). Opracowalem metode zastepcza polegajaca na:
* przepisaniu wszystkich danych z pliku A az do miejsca X do pliku B
* po dotarciu do miejsca X w pliku A zamiast przepisac znajdujace sie tutaj dane do pliku B wpisuje nowe dane (z pamieci)
* pomijam miejsce X i kontynuuje przepisywanie do pliku B z pliku A od miejsca X+1.
Metoda dziala sprawnie, ale jak nietrudno sie przekonac, przy plikach parumegowych zabiera bardzo duzo czasu, szczegolnie jezeli aktualizacji dokonuje co chwile. Nie da sie w jakis prostszy sposob "po prostu" zaktualizowac danych w pliku? Dojsc do danego miejsca, uzyc czegos co mogloby sie nazywac fupdate(*adres,*zaktualizowana_zmienna), co robilo by to samo, ale duzo szybciej, bez zbednego przepisywania calosci?

Licze na Was ;).






20.04.2002
20:15
[2]

Theddas [ Konsul ]

up, zalezy mi :)

20.04.2002
22:03
[3]

MOD [ Generał ]

1.Niestety w szczegoly kompilatorowe i pamieciowe dokladnie sie nie wglebiam , ale moze sprobuj zwalniac pamiec gdy usuwasz element (polecenie free). 2.* przepisaniu wszystkich danych z pliku A az do miejsca X do pliku B * po dotarciu do miejsca X w pliku A zamiast przepisac znajdujace sie tutaj dane do pliku B wpisuje nowe dane (z pamieci) * pomijam miejsce X i kontynuuje przepisywanie do pliku B z pliku A od miejsca X+1. Czy naprawde potrzebujesz pliku B?Ustawiasz w pliku A , wskaznik w dane miejsce , dalej jedziesz w dol i kasujesz wszystko, wracasz w dane miejsce i wpisujesz dane. Albo ustawiasz w dane miejsce , wpisujesz dane (na tamte stare), to co jest nizej kasujesz lub nie. Takie sa moje pomysly. Mam nadzieje ze choc troche Ci pomoglem.

20.04.2002
22:19
[4]

shard [ Pretorianin ]

ja rowniez nie bardzo wiem jak z ta pamiecia (zawsze wywoluje malloc() na tyle ile mi potrzeba, potem zwalniam i jakos mi sie nie zdarzyl jeszcze problem z pamiecia :( - jednak nie pisze na DOS'a... ) co do pliku to jesli struktury sa rowne (zawsze po x bajtow) to przeciez mozesz zrobic tak: a) mozesz do struktury dodac char (lub bool jak wolisz) oznaczajacy czy dana struktura jest "aktywna" czy nie. Jesli jakiejs nie potrzebujesz to dajesz fseek do niej i zaznaczasz bool/char = 0. kiedy potrzebujesz dopisac nowa przelatujesz przez struktury i nadpisujesz pierwwsza ze znacznikiem = 0. (wlasciwie to mozesz dodac tablice pamietajaca ktore struktury zostaly "zwolnione" wtedy bedzie szybciej niz mielic HD za kazdym razem) b) jesli za kazdym razem kiedy "wyrzucasz" strukture dopisujesz nowa daruj sobie znaczniki i tablice i od razu nadpisuj (fseek, fwrite :)

21.04.2002
12:34
[5]

Theddas [ Konsul ]

Z problemem nr 2 juz sobie poradzilem. Smieszna sprawa, ale... fseek dzialal u mnie blednie az do restartu kompa. Jak to sie objawialo? Otwieralem plik r+b (binarny do odczytu i zapisu), fseekowalem sie do odpowiedniego miejsca w pliku i uzywalem fwrite. Wszystko niby dzialalo, ale zamiast aktualizowac strukture w danym miejscu to _dodawana_ byla nowa struktura miedzy poprzednia a nastepna. Po restarcie juz nie jest dodawana, ale aktualizowana. Wiem, ze dziwne, ale grunt, ze teraz dziala :). Oswiadczam wiec, ze ten problem jest juz nieaktualny. Dziekuje wszystkim, ktorzy probowali mi pomoc :). A co problemu nr 1... Tak, wiem, ze powinienem zwalniac pamiec (free, farfree) i robie to, ale chodzi o to, ze jednorazowo potrzebne mi jest okolo 200-300kb pamieci (ale jestem wymagajacy :P), a coreleft czy farcoreleft pokazuja 62kb wolnego i nie wiem jak sie dostac do reszty (dokladnie opisalem to wyzej)...

21.04.2002
15:36
[6]

Kubol [ Pretorianin ]

Theddas--> funkcje typu malloc, calloc alokują pamięć ze sterty programu, która może mieć maksymalnie 64kB ( ale nigdy tyle nie ma , co więcaj sterta dzieli pamięć ze stosem - czyli np. przy uzwaniu dużych zmiennych lokalnych w funkcji i/lub wywołń rekurencyjnych powiększa się stos, więc maleje potencjalnie wolna pamięć na stertę ). Nigdy nie potrzebowałem więcej , ale sprawdziłem z ciekawości i wydaję się, że potrzebna Ci jest funkcja farmalloc() z <alloc.h> będziesz musiał deklarować wskaźniki ze słówkiem kluczowym far Teraz już wiesz czego szukać, więc chwila z helpem i będzie ok.

21.04.2002
17:22
[7]

Theddas [ Konsul ]

Kubol => Gdyby to bylo takie proste... wiesz, jednoczesnie zadalem to samo pytanie na pl.comp.lang.c i tam wlasnie pisalem, ze farmalloc rowniez nie robi tego co powinien, a tutaj zapomnialem, wiec teraz to nadrobie :). Otoz... gdy zamieniam malloc na farmalloc i coreleft na farcoreleft to wartosci pokazywane sa IDENTYCZNE jak bez "far". Co gorsza, gdy wywoluje jednoczesnie farcoreleft i coreleft to pokazywane sa te same wartosci niezaleznie od tego czy uzywam malloc czy farmalloc, czyli jak gdyby te komendy byly identyczne. Zdazylem juz przejrzec calego helpa dotyczacego alloc.h i to bylo pierwsze co probowalem, ale nic z tego :/. Albo cos zle robie, ale o czyms zapominam, tylko nie wiem o czym. Nawet w glupim Pascalu funkcja pokazujaca dostepna pamiec (zapomnialem nazwy :) pokazuje domyslnie ~450kb, czyli jakos sobie z tym Pascal sam radzi, a tutaj... hm...

21.04.2002
22:10
[8]

Kubol [ Pretorianin ]

Theddas--> farcoreleft i coreleft niekoniecznie pokazują ilość wolnego miejsca w pamięci ! (tak jest tylko dla małych modeli pamięci ) Pokazują ilość pamięci, jaka pozostała od "najwyższego" bloku zaalokowanego na stercie ( i tutaj w przypadku Huge memory model zdaje się, że funkcje poprostu są tożsame, dlatego pokazują to samo) do końca wolnej pamięci. Sterta natomiast w przeciwieństwie do stosu nie jest obszarem spójnym !, więc wartości pokazywane przez te funkcje poprostu niec nie znaczą! Sprawdziłem to i - farcoreleft pokazał mi 1230 bajtów, a bez problemu zaalokowałem sobie 300K . I tyle. Trochę to śmieszne. Z drugiej strony wartości pokazywane przez te funkcje mówią tylko ile na pewno masz ( bo nie ma pewności, czy sterta nie jest przypadkiem cała zapełniona ) pamięci do dyspozycji.

21.04.2002
22:14
[9]

Kubol [ Pretorianin ]

Jeszcze jedno. Zdaje się, że można sobie obliczyć ile masz w rzeczywistości wolnej pamięci. Używając farheapwalk() jesteś w stanie dostać rozmiary i adresy wszystkich bloków na stercie ( czyli można sobie zrobić małą analizę zajętości pamięci - i to pewnie robią funkcje pascalowskie ) Mam nadzieję, że tym razem napisałem coś pomocnego.

21.04.2002
22:16
[10]

Theddas [ Konsul ]

Tak, zgadzam sie. Caly problem sprowadza sie do tego jak sprawic, zeby farmalloc (niekoniecznie malloc) pozwalaly adresowac zmienne w innych niz ten, ktorego "zajetosc" pokazuja farcoreleft i coreleft. U mnie Twoj sposob jakos nie chce dzialac :/. Przy probie alokowania 20kb pamieci farmallociem gdy farcoreleft pokazuje np. 10kb dostaje blad, a farmalloc zwraca null...

21.04.2002
22:17
[11]

Theddas [ Konsul ]

w innych niz... blokach/segmentach oczywiscie, zjadlo mi slowo :))

22.04.2002
20:41
[12]

Theddas [ Konsul ]

Ok, problem rozwiazany! Dzieki wszystkim, ktorzy probowali mi pomoc :). Ostatecznie udalo sie na pl.comp.lang.c. Jeszcze raz dzieki. PS. Jezeli moderatorzy chca skasowac ten watek to nie widze problemu oczywiscie, po co ma lezec bezczynnie.

© 2000-2021 GRY-OnLine S.A.