|
dev.gamez.lv Latvian Game Developers Community
|
View previous topic :: View next topic |
Author |
Message |
S1 Indago dalībnieks
Joined: 31 Jul 2005 Posts: 219 Location: Jelgava
|
Posted: Thu Apr 27, 2006 5:10 pm Post subject: BlockRead - atmiņas atbrīvošana |
|
sveiki, kā lai atbrīvo atmiņu pēc šīs operācijas? piem.
Code: | BlockRead(TGAFile, TGAHeader, SizeOf(TGAHeader)); |
|
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Thu Apr 27, 2006 6:38 pm Post subject: |
|
Ja tas ir Turbo paskāls, Delphi vai Free paskāls, tad man tev ir jautājums - kopš kuriem laikiem BlockRead izdala atmiņu? Blockread taču tikai nolasa failu iekš atmiņas vietas, kuru tu padod otrajā parametrā, un viss. Nekāda atmiņas izdalīšana nenotiek taču! |
|
Back to top |
|
|
S1 Indago dalībnieks
Joined: 31 Jul 2005 Posts: 219 Location: Jelgava
|
Posted: Thu Apr 27, 2006 7:11 pm Post subject: |
|
nu jā... |
|
Back to top |
|
|
S1 Indago dalībnieks
Joined: 31 Jul 2005 Posts: 219 Location: Jelgava
|
Posted: Thu Apr 27, 2006 8:50 pm Post subject: |
|
vēl viens gadījums: gribās atbrīvot atmiņu ko bija rezervējis ieraksts:
Code: |
type
THeader = record
FileType : Byte;
ColorMapType : Byte;
end;
//pointeris priekš šī ieraksta
type TPointer = ^TtGAHeader;
var
TGAFile : File;
tgaHeader : TtgaHeader;
p : TPointer;
begin
AssignFile(TGAFile, address);
Reset(TGAFile, 1);
BlockRead(TGAFile, TGAHeader, SizeOf(TGAHeader));
p := @tgaHeader; // tā, šeit es norādu ieraksta adresi
freeMem(p); //tipa mēģinu atbrīvot ieraksta aizņemto atmiņu
|
beigu beigās parādās errors ka ....blablablablablablabla so... kāds te būtu risinājums???? |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Apr 28, 2006 1:31 am Post subject: |
|
var tgaHeader : TtgaHeader;
izdala atmiņu stekā nevis heapā. Tātad atmiņa pati atbrīvosies izejot no redzamības (scope), tb end. Ja tu izdalītu atmiņu ar getmem/new, tad tikai tādā gadījumā tev vajadzētu saukt atbilstoši freemem/dispose. |
|
Back to top |
|
|
S1 Indago dalībnieks
Joined: 31 Jul 2005 Posts: 219 Location: Jelgava
|
Posted: Fri Apr 28, 2006 11:53 am Post subject: |
|
ok, skaidrs. liels paldies.
varbūt pastāsti tā īsumā par steku un heapu, plzzz. (citiem tas arī var noderēt) |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Fri Apr 28, 2006 12:34 pm Post subject: |
|
Nu steks ir viena no lietām, kas nodrošina funkciju izsaukumus uz PC (un arī citām) arhitektūrām. Steks tiek realizēts kā pointeris uz parastu masīvu atmiņā. Kad tiek izsaukta funkcija, tad visi mainīgie tai tiek salikti stekā (steks ir LIFO struktūra), un vadība tiek nododa uz funkciju, pirms tam ieliekot stekā vēl atgriešanās adrese (tb uz kurieni jāpadod vadība, kad funkcija beigsies). Funkcija sākot savu darbu (vienkāršākajā gadījumā) pabīda steka pointeri vēl uz leju par izmēru, kas vienāds ar visu lokālo mainīgo kopējo garumu. Šī atbrīvotajā atmiņas vieta arī tiek izmantot tavam TGAFile, tgaHeader un p. Funkcijai beidzot darbu steka pointeris tiek pabīdīts atpakaļ par to lokālo mainīgo kopējo garumu (tādējādi automātiski atbrīvojas atmiņa). Un vadība tiek atgriezta atpakaļ uz adresi, kas tagad vēl palikusi stekā. Papildus tam tādas valodas kā paskāls izvelk ieliktos argumentus stekā, lai izsaucošajam kodam vairs nav jāraizējas kas tur ielikts. Taču tādas valodas kā C/C++ atstāj tos parametrus tur, un izsaucošais kods pats iztīra to. Te rodās dažas optimizācijas iespējas, kad vajag diviem dažādu vai vienādu funkciju izsaukumiem vajag pilnīgi vienādus vai kopējus argumentus. C/C++ gadījumā argumenti tur jau būs, un nevajadzēs likt pa jaunam. Taču paskāla gadījumā visu vajadzēs pa jaunam likt stekā. Tas tā nedaudz offtopikā, bet zināt der. Steka priekšrocības ir tieši tādas, ka atmiņa pati atbrīvojas, noteik ātra atmiņas izdalīšana (salīdzinājumā ar heapu), taču viens no mīnusiem - relatīvi neliels izmērs (salīdzinājumā ar heapu). Tāpēc parasti stekā liek neliela apjoma objektus. Jāatcerās arī, ka stekā izdalīto atmiņu var lietot tikai viena scopa ietvaros (starp begin un end, vai starp { un }). Jo citā funkcijā svešas funkcijas steks nav pieejams.
Par hepu runājot. Priekšrocība - praktiski neierobežots izmērs (tik cik atmiņa ļauj). Mīnuss - lēna atmiņas izdalīšana, fragmentācija daudz un bieži izdalot/atbrīvojot atmiņu. Tāpēc heapu lieto objektiem/struktūrām, kuras aizņem daudz atmiņas, vai nepieciešama atmiņas padošana starp dažādām funkcijām. Heapas parasti tiek realizēts kā pointeris uz atmiņas apgabalu. Jāatcerās arī, ka heaps pats neatbrīvo atmiņu (ja nu vienīgi pašai programmai beidzoties, kad OS pati attīra programmas aizņemot atmiņu).
Ja nu vajag piemērus, tad paskālam heapa izmantošana:
Code: | var
Pint: ^integer;
Pbuffer: pointer;
begin
New(Pint); // tiek izdalīts tipizēts(tā laikam tas saucās?) mainīgais
// garums tiek noteikts automātiski no mainīgā tipa=2 (ja turbo pascal)
GetMem(Pbuffer, 1024); // tiek izdalīti 1024 baiti vispārīgam pointerim
...
Dispose(Pint); // atbrīvo Pint
FreeMem(Pbuffer); // atbrīvo Pbuffer
end; |
Par steka mainīgajiem runājot, iepriekšējā piemērā ir divis teka mainīgie - pointeris uz integer, un parasts pointeris uz kautkurieni. Šie abi tiek likti stekā un tiem atmiņa atbrīvojās automātiski. Tikai nevajag jaukt atmiņu, ko aizņem pats pointeris, ar atmiņu, uz kuru norāda tas pointeris (heapā).
C kodā:
Code: | {
int* p = (int*)malloc(sizeof(p)); // C++ kodā: new int;
char* c = malloc(1024); // C++ kodā: new char[1024];
...
free(p); // C++ kodā: delete p;
free(c); // C++ kodā: delete [] c;
} |
C++'ā tikpat labi int vietā var likt klases nosaukumu:
Code: | {
Klase* H = new Klase(1,2, "aaa");
Klase S(3, 4, "bbb");
...
delete H;
} |
Klase objekts, uz kuru norāda H pointeris (jo zvaigznīte), tiek izdalīts heapā (jo new), taču S objekts tiek izdalīs stekā un tiek automātiski atbrīvots pie } simbola.
Vajag, protams, saprast, ka šāda veida konstrukcijas nevajag taisīt (paskālā arī, šādi tu darīji savā kodā):
Code: | {
Klase K(11, 22, "ccc); // izveido jaunu K objektu
Klase* P = &K; // izveido pointeri P uz objektu, kurš norāda uz klasi
...
delete P; // atbrīvojam atmiņu uz kuru norāda P. Te visdrīzāk programm krešos
} |
Atbrīvojot P tu jau īstenībā atbrīvosi K, kas tika taisīts stekā. Un mēģināt atbrīvot steka mainīgo ar heapa atbrīvošanas funkciju visdrīzāk ved pie kreša.
Palasīšanai internetā:
http://web.syr.edu/~nshenvi/rtas.pdf
http://www-ee.eng.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.8.html
http://www.cs.jcu.edu.au/Subjects/cp2003/1997/foils/heapAndStack/heapAndStack.html
http://www.awitness.org/delphi_pascal_tutorial/c++_delphi/c++_pointer_stack_heap.html
Last edited by bubu on Fri Apr 28, 2006 2:49 pm; edited 2 times in total |
|
Back to top |
|
|
S1 Indago dalībnieks
Joined: 31 Jul 2005 Posts: 219 Location: Jelgava
|
Posted: Fri Apr 28, 2006 12:48 pm Post subject: |
|
paldies bubu, vispār saprotami uzrakstīts, normāli. Izskatās pēc neliela tutoriāļa |
|
Back to top |
|
|
Tenjou
Joined: 22 Nov 2005 Posts: 275
|
Posted: Wed Aug 22, 2007 1:42 pm Post subject: |
|
Ja izveido, piemēram:
Code: | struct Struktura {
int skaitlju_bufferis[100];
}
...
JaunaStruktura = new Struktura[5];
|
... 'skaitlju_bufferis' būs iedalīta vieta heapa vai stekā? |
|
Back to top |
|
|
snake5 Indago dalībnieks
Joined: 27 Jun 2007 Posts: 2590
|
Posted: Wed Aug 22, 2007 3:06 pm Post subject: |
|
ar new un malloc atminju iedala heap'aa _________________ "There are two choices here: "looks good" and "realism"." -- Paul Nettle |
|
Back to top |
|
|
Tenjou
Joined: 22 Nov 2005 Posts: 275
|
Posted: Wed Aug 22, 2007 3:49 pm Post subject: |
|
Tas ir skaidrs, bet man interesē tieši, vai ja inicializē/izveido jaunu struktūru ar 'new'. Visas struktūras memberiem tiek iedalīta atmiņa heapā, vai tiek tikai iedalīta atmiņa pašai struktūrai, bet tās memberiem atmiņa stackā? |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Wed Aug 22, 2007 4:11 pm Post subject: |
|
Struktūra = atmiņas klucis.
new Struktūra = izdalīt struktūru heapā = izdalīt atmiņas kluci heapā.
Tavā piemērā heapā tiek izdalīta visas strukūras atmiņa, taču stekā tiek izdalīta vieta pointerim uz struktūru (JaunStruktura mainīgais). |
|
Back to top |
|
|
snake5 Indago dalībnieks
Joined: 27 Jun 2007 Posts: 2590
|
Posted: Wed Aug 22, 2007 5:40 pm Post subject: |
|
kad saaku taisiit savu projektu, pavisam par atminjas izdaliishanu biju aizmirsis, taapeec salaidu tur daudz kljuudu... neiesaku dariit shitaa.. _________________ "There are two choices here: "looks good" and "realism"." -- Paul Nettle |
|
Back to top |
|
|
bubu Indago Uzvarētājs
Joined: 23 Mar 2004 Posts: 3223 Location: Riga
|
Posted: Wed Aug 22, 2007 6:58 pm Post subject: |
|
Ja negrib domāt par atmiņas izdalīšanu, tad vajag programmēt .NET freimworkā (C#, VB.NET), Python, Ruby, vai citās programmēšanas valodās, kurās ir atmiņu pārvalda garbage-collector's. Būs daudz vieglāk. Vajag izvēlēties pareizo rīku (valodu) pareizajam darbam. Nav vienas programmēšanas valodas, kura ir vis-vis-labākā jebkuriem programmu veidiem. |
|
Back to top |
|
|
snake5 Indago dalībnieks
Joined: 27 Jun 2007 Posts: 2590
|
Posted: Wed Aug 22, 2007 8:23 pm Post subject: |
|
man iisteniibaa vieniigaa valoda, kura patiik ir cpp.. neviena cita mani taa iisti neinteresee.. man arii pilniigi vienalga, cik ar cpp ir gruuti kautko izdariit.. iemaaciishos CPP jebkaadaa veidaa! domaaju kautkad ciitiigi paarlasiit kaadu tutoriaali .. _________________ "There are two choices here: "looks good" and "realism"." -- Paul Nettle |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|