Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: c geheugen reseveren wel of niet  (gelezen 3330 keer)

Offline xellos

  • Lid
c geheugen reseveren wel of niet
« Gepost op: 2010/01/19, 20:11:05 »
is het verstandig om altijd geheugen te reseveren voor variabelen arrays en structs?

waneer wel waneer niet?

Offline Joshua822

  • Lid
Re: c geheugen reseveren wel of niet
« Reactie #1 Gepost op: 2010/01/19, 21:40:46 »
Citaat
is het verstandig om altijd geheugen te reseveren voor variabelen arrays en structs?

waneer wel waneer niet?

Ja / Nee. Je mag het wel, maar het heeft weinig nut. Het reserveren van geheugen doen we in de praktijk als we vanuit een pointer rechtstreeks naar informatie ( dus niet een pointer naar een variabel! ) willen verwijzen. Bijvoorbeeld : we willen ergens in het geheugen het getal 75630 opslaan, en er dan direct met een pointer naar verwijzen en beheren. Moeten we dan eerst een "integer" variabel maken om het getal in op te slaan en daarna een pointer naar deze variabel maken ? Dit kan perfect. Maar dit is verspilling van RAM geheugen, want we kunnen net zo goed alleen de variabel gebruiken. Daarom vragen we eerst met een functie als "malloc" een stukje RAM geheugen aan, de functie geeft ons het geheugenadres van dit stukje RAM geheugen, en we kunnen via deze pointer de informatie in dit stukje geheugen beheren. We hebben dus geen twee variabelen nodig : de pointer naar de "integer" variabel en de "integer" variabel zelf. We hebben enkel de pointer variabel nodig om het geheugenadres van ons stukje geheugen te bewaren. Dit klinkt allemaal redelijk omslachtig, maar het nut van deze techniek wordt snel duidelijk als je datastructuren gaat programmeren.

Deze techniek levert trouwens geen lager RAM geheugen gebruik van je programma op.

Hier is het voorbeeld in de praktijk:
unsigned int * pointer_naar_waarde;
waarde = ( int * ) malloc ( sizeof ( int ) );
* waarde = 75630;

in plaats van:
unsigned int waarde = 75630;
unsigned int * pointer_naar_waarde = &waarde;

Ik hoop dat je het begrijpt! Anders zeg je het maar even :)

Offline Emil

  • Lid
Re: c geheugen reseveren wel of niet
« Reactie #2 Gepost op: 2010/01/20, 18:09:09 »
@Joshua822
Eerst zeg je dat de ene methode verspilling van RAM is, daarna zeg je dat de andere methode geen lager RAM gebruik oplevert. Wat is het voordeel dan wel, of begrijp ik je verkeerd?

Offline Joshua822

  • Lid
Re: c geheugen reseveren wel of niet
« Reactie #3 Gepost op: 2010/01/20, 18:40:03 »
Citaat
@Joshua822
Eerst zeg je dat de ene methode verspilling van RAM is, daarna zeg je dat de andere methode geen lager RAM gebruik oplevert. Wat is het voordeel dan wel, of begrijp ik je verkeerd?

Kijk naar het volgende broncode voorbeeld:
unsigned int waarde = 75630;
unsigned int * pointer_naar_waarde = &waarde;
Dus zoals ik al uitgelegd heb, willen we enkel een pointer gebruiken om naar bepaalde informatie te verwijzen. Nu, met de techniek, gedemonstreerd in het broncodevoorbeeld hierboven, maken we eerst een variabel aan die onze informatie bevat, daarna maken we een pointer naar deze variabel aan, om vervolgens de waarde in die variabel te beheren via de pointer.
Nu, in plaats van het bovenstaande broncodevoorbeeld zouden we eigenlijk gewoon de variabel zo kunnen gebruiken. Die extra pointer voor het beheren heeft gewoonweg geen enkel nut met deze techniek. Daarom is dit verspilling van RAM geheugen : als we net zo goed met alleen die variabel zouden kunnen werken, waarom zouden we dan nog RAM geheugen verbruiken voor het opslaan van een pointer naar deze variabel ?
Maar daar komen we niet verder mee: we willen namelijk via een pointer de informatie op het naar verwezen geheugenadres beheren. Dus, gebruiken we de techniek, die ik al eerder in dit draadje uitgelegd heb. Dit gebruikt hetzelfde aantal RAM geheugen als de vorige techniek. Waarom verspillen we met deze techniek dan geen RAM geheugen ? Heel simpel: de opgeslagen informatie neemt dezelfde hoeveelheid geheugen in beslag, maar deze informatie is "gewoon" in het RAM geheugen opgenomen, dus zonder een variabel. Alleen de pointer bied ons een manier om de informatie te beheren. Dus met deze techniek heeft de pointer wel nut. En als we geheugen nuttig gebruiken, verspillen we geen RAM geheugen.

Ik hoop dat het duidelijk is :) Sorry, ik moest rap zijn, ik heb morgen twee grote proefwerken. 

Offline muksie

  • Lid
Re: c geheugen reseveren wel of niet
« Reactie #4 Gepost op: 2010/01/26, 15:53:42 »
Beetje late reactie misschien, maar zie dit topic nu pas en ik kom de laatste tijd hier niet meer zo vaak...

Het verschil tussen wel en niet reserveren van geheugen zit in het feit dat het geheugen wat een programma gebruikt, opgedeeld is in twee soorten.

Enerzijds is er de stack. Hier komen in principe alle variabelen in te staan. Vanwege de opbouw van C-code kan automatisch geheugen op de stack gereserveerd worden wanneer dit nodig is, en weer vrijgegeven wanneer het niet meer nodig is. Roep je bijvoorbeeld een functie aan met een lokale variabele, dan wordt ten tijde van de aanroep geheugen voor deze variabele gereserveerd, en door het return statement weer vrijgegeven.

In de meeste gevallen voldoet het geheugen op de stack prima. Er zijn echter ook tal van situaties te bedenken waarin dit niet het geval is. In dat geval kun je gebruik maken van het geheugen op de heap. Met malloc (of calloc) kun je een stuk geheugen op de heap reserveren. Vervolgens krijg je enkel een pointer naar het voor jou gereserveerde geheugen terug, ofwel een geheugenadres. Deze dien je vervolgens natuurlijk wel ergens op te slaan, in de meeste gevallen is dit gewoon op de stack.

Omdat je het geheugen handmatig gereserveerd hebt, is niet automatisch bekend wanneer het geheugen niet meer nodig is. Dit moet je dan ook zelf doen! Vrijgeven kan met de free functie. In de meeste gevallen wil je bij elke malloc / calloc aanroep ergens een corresponderende free aanroep. Doe je dit niet, dan loop je het risico dat je programma geheugen 'lekt'.

Samengevat: Gebruik de stack waar mogelijk, maar mocht de stack in een bepaald geval niet voldoen, gebruik dan geheugen op de heap (en zorg dat je het ook weer vrijgeeft).

Ga alleen geen variabelen op de stack proberen vrij te geven met free, want dat is vragen om problemen. Bedenk ook dat een pointer niet noodzakelijk naar geheugen op de heap verwijst.