» »

Pomnilnik in c++

Pomnilnik in c++

Vlady ::

Sedaj bom mogoče izpustil malo glupo vprašanje, ampak me vseeno zanima:

Do sedaj sem večinoma programiral v Javi in tam je vse lepo poskrbljeno glede "mrtvih" spremenljivk in objektov s strani garbage collector-ja.
Sedaj pa se učim še malo c++ in sem ugotovil, da je tu zelo podobno kot v javi (ni enako je pa zelo podobno). Zanima me, kako pri kakem večjem programu ugotoviš, koliko objektov enega tipa si "uporabil" in koliko pomnilnika ti zasedajo ti objekti. To mislim seveda takrat, ko se program izvaja. Če v winsih odprem task manager, mi tam pokaže koliko prostora mi zaseda celoten program ne pa koliko prostora zasedajo objekti in vse spremenljivke. Gre se predvsem za to, ker se mi objekti generirajo med samim izvajanjem in lahko pride do "prekoračitve" kapacitete pomnilnika.

Drugo vprašanje je pa tudi bolj butasto ampak me tudi "srbi":
Programe pišem v Dev-C++ 4.9.9.2 Če napišem tak program:

#include "iostream.h"
#include "string"
int main()
{
string niz;
string iskani;
string novi;
int lega;
int dolzina;
cout (( "Zapisite zacetni niz: ";
getline (cin, niz);
cout (( "Zapisite iskano besedo: ";
getline (cin, iskani);
cout (( "Zapisite besedo za zamenjavo: ";
getline (cin, novi);
dolzina = iskani.length();
while (true)
{
lega = niz.find(iskani);
if (lega == -1) {break;}
niz.erase(lega, dolzina);
niz.insert(lega, novi);
}
cout (( niz (( endl;
return 0;
}


Oklepajov v prvih dveh vrsticah nisem napisal, ker ne delujejo na forumu v resnici so pravilno zapisani.
Mi prevajalnik vrže ven napako. Prevajalnik ima razred string in tudi nastavitve (poti) do datoteke so pravilni.

Izpis prevajalnika:
D:\programi\string.cpp In function `int main()':
5 D:\programi\string.cpp `string' undeclared (first use this function)
(Each undeclared identifier is reported only once for each function it appears in.)
5 D:\programi\string.cpp expected `;' before "niz"
6 D:\programi\string.cpp expected `;' before "iskani"
7 D:\programi\string.cpp expected `;' before "novi"
11 D:\programi\string.cpp `niz' undeclared (first use this function)
13 D:\programi\string.cpp `iskani' undeclared (first use this function)
15 D:\programi\string.cpp `novi' undeclared (first use this function)

Kaj storiti? :\
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"
  • spremenil: Vesoljc ()

Vesoljc ::

za prikaz kode uporabi tag "st.koda c" z kvadratnimi oklepaji.

kar se pomnilnika tice je tako. kart rabis je en memory manager, lahko ga pac sam naredis, ali pa najdes kakega free na netu. en preprost nacin je pac en staticen seznam, v katerega objekt ob konstrukciji doda svoj pointer (this), od desktrukciji pa ga izbrise ven. tako imas v runtime-u seznam alociranih objektov. koliko placa zasedejo je pa spet drug problem. sizeof ti vrne velikost objekta, ampak to je le compile time funkcija. ce objekt vsebuje dinamicno alociran pomnilnik, moras to sam steti. poguglaj za "memoy manager c++" ali kaj podobnega.

glede zgornja programa pa tole:

pozabi na *.h!

#include <iostream>
#include <string>

using namespace std;

// ostalo


ps: preberi si tudi clanek na slotehu
Abnormal behavior of abnormal brain makes me normal...

OwcA ::

Ko uporabljaš neelementarne tipe je treba pri računanju porabe pomnilnika še dodatno paziti na pribitke, ki jih lahko prinese poravnava.
Otroška radovednost - gonilo napredka.

Vlady ::

@Vesoljc hvala ti za "porpavek" mojega programa, ampak se učim tole iz ene knjige in tak je notr pisal. Tvoja zadeva deluje :D Glede članka me samo zanima naslov članka in v kateri kategoriji je?

Glede pomnilnika me zanima zaradi izdelave ene igre. Pa dam recimo primer: imaš strategijo, kjer je vsaka enota svoj izvod objekta. Torej en tip vojakov ima svoj razred in potem vsakokrat ko hočeš "narediti" novega vojaka kličeš konstruktor in ti naredi nov objekt. Mene zanima kolikokrat lahko kličem ta konstruktor preden zapolnim pomnilnik oz. koliko prostora mi zasede če kličem konstruktor 100x, 200x, 1000x? No mal sem zakompliciru stvar ampak zaenkrat se tole še bolj učim in mi nekaj stvari preprosto ne gre skupaj. :\ Tud v javi sem srečal podoben primer, vendar sem potem tam našel "programček" za diagnostiko izvajanja in sem nekako videl koliko zasede celoten program, nisem pa videl koliko zasede določen objekt. "memoy manager c++" v guglu ne najde kaj preveč perspektivnega :\
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

OwcA ::

Moram priznati, da mi ni čisto jasno, zakaj bi to rabil.

stran na http://www.slo-tech.com/clanki/04009/04...
Otroška radovednost - gonilo napredka.

Vlady ::

Ja predvsem zato, da mi nebi program zasedel preveč spomina oz. da vidim koliko ga potrebujem. :)
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

BigWhale ::

Tako na pamet bi lahko rekel, da lahko en objekt instanciras priblizno sizeof(free_ram) / sizeof(objekt).

Priblizno. :)

no in ce je vojak definiran z parametri x,y,z,tipom,zdravjem,mocjo

Imas potem long,long,long,int,int,int ~= 24 bytov
Torej, ce imas prostega 400MB spomina po tem, ko startas to strategijo, laho ustvaris priblizno 16666666,666666666666666666666667 vojakov.

A bo dost? ;)

Gundolf ::

Če je tvoj objekt katerega velikost te zanima POD (Plain Old Data) ali podoben enostaven razred potem ti njegovo velikost pove operator sizeof
std::cout << sizeof(int) << ", " << sizeof(double) << std::endl;  // izpis bo 4, 8, kar pomeni da int zasede 4, double pa 8 bajtov

// POD razred
class Unit {
   int x, y;
   int health;
   char type;
   // itd
};
std::cout << sizeof(Unit); // bo izpisalo vsaj 13 in to bo dejanska velikost razreda

// kompleksen razred
class Info {
   std::string name;
   // itd
}
std::cout << sizeof(Info); // bo izpisalo neko cifor, ki pa ne pomeni nujno dejanske velikosti razreda.


Vsi objekti, ki dinamično alocirajo pomnilnik ali vsebujejo take objekte (string) lahko zavzamejo več prostora kot ti vrne sizeof. Zato ne moreš tako enostavno določiti njihove velikosti. Še boljši primer je recimo dreve, katerede sizof(Root) si lahko predstavljaš bo daleč od velikosti celotnega drevesa. Torej če so tvoje enote enostavne si lahko izračunaš velikost ene in tako vidiš, koliko jih lahko imaš v spominu preden ti zasedejo več kot recimo 64MB. A si to hotel?

edit: lol BW, kot da bi od tebe kopiral tega vojaka :)

Zgodovina sprememb…

  • spremenil: Gundolf ()

Vlady ::

@Gundolf hvala za pomoč, gre za malo bolj kompleksne "vojačke". Po mojih izračunih naj bi vsak zasedel približno 30byte-ov. Ampak to zgolj če računam koliko "požre" posamezen podatek. Po prevajanju pa ne vem koliko bo realno potreboval posamezen objekt. No zanima me samo še to, kaj se recimo zgodi, če prekoračim število objektov (torej več kot imam spomina). Sej ne da bi jaz imel premalo rama (imam ga 1,5GB) ampak gre se za to, da se bo dalo potem program ganjati tudi drugje recimo na kakih 256MB. :\
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

OwcA ::

Če zasegaš pomnilnik z operatorjem new boš dobil exception.
Otroška radovednost - gonilo napredka.

Gundolf ::

Jaz ti pa svetujem da to prekoračitev enostavno probaš. Boš najbolje vedel. Naredi strukturo vojačka in nato eno tabelo teh vojačkov, ki bo po tvojih izračunih prevelika za tvojo količino rama. Verjetno najprej ne bo exceptiona ampak boš dobil malo prelaganja po disku. Če te skrbi, da bi med igro prekoračil neko prej postavljeno mejo pa preprosto štej število vojačkov, ki jih narediš in ga vnaprej omeji. Recimo v konstruktorju povečaj nek globalni counter, v destruktorju ga zmanjšaj. Vsakič preden narediš novega to številko preveri in ustrezno ukrepaj. Čeprav dvomim da boš pri svoji igri lahko zapolnil spomin z vojsko 30 b velikimi enotami.

Aja, pa tule predstavi tvojo strukturo in pa kako jih boš hranil eno množico (v tabeli, v linked listi, v drevesu...), če ni skrivnost. Pa ti lahko takole na uč takoj povemo koliko več od 30 b ti bo zasedel posamezen objekt oz. ti svetujemo kaj lahko izboljšaš.

Pa še en nasvet vnaprej: najprej naredi da bo (dobro) delalo z nekaj malega enotami, potem te lahko skrbi kako bo, če bo enot preveč.

Zgodovina sprememb…

  • spremenil: Gundolf ()

Senitel ::

Če prekoračiš količino pomnilnika, ki ga ima OS na razpolago, potem bo OS začel tlačit stvari v virtual memory. Exception boš dobil šele, ko tudi OS obupa z šarjenjem po VM ali, ko bi tako šarjenje porabilo preveč časa.
Kot je že tudi bilo omenjeno ti kompleksnejše strukture lahko pokurijo več rama, kot ti pove sizeof ali seštevanje vsebine na roke. Lahko pa forsiraš pri compilerju poravnave na 1 byte.

Vlady ::

Hvala vam za odgovore, edino kar me skrbi, da se nebi program "zaciklu" pr porabi pomnilnika. Torej da nebi požrl ves RAM za OS in potem se mi lahko zgodi, da sistem "obvisi" zarad programa ker nima RAM-a. :\

Pa še mogoče malo neumesno vprašanje: kako se uporablja miško v c++. Recimo v win API, kako dobiti koordinate miške in odzive na gumbe? :\ Kak primer kode bi mi bil zelo dobrodošel. V javi imaš poslušalce in to je to, tu pa nimam pojma. V nobenem tutorialu, ki jih imam pa ne piše kako narediti odzive na miško, tipkovnico... Grem pa še mal poguglat. :)
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

BigWhale ::

> Če prekoračiš količino pomnilnika, ki ga ima OS na
> razpolago, potem bo OS začel tlačit stvari v virtual
> memory. Exception boš dobil šele, ko tudi OS obupa z
> šarjenjem po VM ali, ko bi tako šarjenje porabilo preveč
> časa.

Ne bom dal roke v ogenj ampak vsak pameten OS bi naredil stvar tako, da bi, ce bi zmanjkovalo rama, odswappal stvari, ki ne laufajo v swap in porabil tisti ram, ki ga je s tem pridobil, ce mu ne bi ostalo nic vec za odswappat, bi javil, da nima RAMa.

Nikakor pa ne bi sel alocirat spomina v virtual ram, nekam na disk.

BigWhale ::

Vlady,

Kar se pa miske tice, se pa oprimi kaksne razvojne knjiznice za te stvari. SDL bi bil kar primeren, pa se multiplatform je.

Vlady ::

@Bigwhale hvala za tale SDL, samo lahko najdeš še kak primer kode?
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

Gundolf ::

Na SDLovi strani je polno kode. Drugače pa je njihov documentation (recimo v html obliki) zelo pregleden in notri hitro najdeš vse o miši, tipkovnici, čemur hočeš. Mislim da je celo nekaj primerov zraven.

Drugače pa še vedno ostane google sdl tutorial.

BigWhale ::

www.libsdl.org

Se mi zdi, da je site, pa je kar v redu dokumentirana zadeva. Se vojake bos lahko risal ;)

Vlady ::

Big HVALA vsem za pomoč :D

Obstajajo kje kakšni slovenski tutoriali? Me zanima informativno :)
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

Vlady ::

Em novi problemček:

Zakaj mi vse windows aplikacije, ki jih napišem skoraj 100% obremenijo procesor? Naj gre za win API ali SDL. Gre za enostavno okno, ki je prazno ali pa se samo dve barvi prelivata notri. To normalen pojav ali sem jaz kaj narobe napisal? :\
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

Gundolf ::

To imaš tako napisano - verjetno je neka glavna zanka, ki jo program zapusti šele ko ga zapreš. Program ti namreč stalno dela, nič ne čaka, zato je CPU 100% zaseden. Če bi hotel to spremeniti bi lahko recimo naredil vse izračune in osveževanje ekrana na vsake 10 milisekund z nekim timerjem, vmes pa bi sistem dodelil CPU drugim procesom.

Mmm'Aah ::

Jedro vsakega pograma, ki se odziva na neke dogodke je t.i. Message Loop ali Event Loop. To je zanka, znotraj katere se sporočila "Messages" oz. dogodki, kot bi jih površno lahko imenovali, obravnavajo na dva načina:

1. Lahko ČAKAŠ na dogodek, in potem ob dogodku (če te ta konkretni dogodek zanima) spremeniš in izvedeš v programu vse kar je potrebno. Tak program ne more ves čas osveževati grafike, ker ubistvu skoraj ves čas čaka in začne delati, le ko pride do "dogodka". To pa ne pomeni, da se gumbi na katere uporabnik klika ne bodo osveževali ali kaj podobnega, ker je ta osnovna grafika obravnavana že s strani operacijskega sistema oz. natančneje njegovega Windowing System-a. Vsa grafika osnovnih kontrol se bo osveževala kot je to potrebno, dodatne stvari pa se bojo dogajale le kot odzivi na dogodke. Ta način porabi ZELO MALO procesorskega časa. TAKIH JE VEČINA PROGRAMOV.

2. Lahko PREVERIŠ če so v "bazenu sporočil" (Message Pool) kakšna sporočila o dodkih, ter jih obravnavaš takrat kot pridejo, če pa sporočil ni, vseeno NADALJUJEŠ zanko in kličeš kako funkcijo ki se preko zanke vseskozi ponavlja, v njej pa stalno osvežuješ vse kar je pač treba osveževati. Med te vrste programov spadajo vse aplikacije, ki morajo ves čas nekaj računati, preverjati ali osveževati grafiko. Kot si verjetno že sam ugotovil gre v tem primeru za IGRICE IN PODOBNE PROGRAME. Ker taki programi vse skozi nekaj delajo, je logično da zasedejo VES PROCESORSKI ČAS.

Čakanju na dogodek se ponavadi reče "WaitMessage", preverjanju če je v bazenu kak dogodek "PeepMessage", vzemanju dogodka iz bazena pa "PollMessage". prav tako se običajno tudi kličejo funkcije, ki jih je za izbrano tehniko potrebno klicati.

Vesoljc ::

IGRE lepo prosim!

aja, pa držite se teme lepo prosim. če pa vam zmanjka idej o memory managmentu v c++ (v kar dvomim), bom prisiljen temo zakletniti! :|
Abnormal behavior of abnormal brain makes me normal...

Zgodovina sprememb…

  • spremenil: Vesoljc ()

Vlady ::

Aha, hvala za tole predavanje o "message"-ih :) Mi je sedaj veliko bolj jasno glede tega :D No trenutno se igračkam z OpenGL in mi kar ratuje. Me pa zanima, če se da spisat "DrawGLScene(GLvoid)" funkcijo v svoji datoteki in potem to datoteko "vključit" v svoj projekt, torej v datoteko, kjer "generiraš" OpenGL okno. Preprosto postane koda zelo nepregledna, če imaš to funkcijo full veliko, še posebej ko se igraš s texturami :) Torej kaj narediti in kako?

@Vesoljx: ne se sekirat če smo mal zašli iz teme, zadeve me pač zanimajo in se mi zdi škoda odpirat 10 tem za 10 vprašanj. Lahko pa spremenič naslov teme, da bo "pokrila" področje vseh vprašanj, če je tako boljše.

Glede memory managment-a pa bi prosil če me nekdo popravi ali potrdi pravilno: V openGL-u generiraš objekte, in če ti zmanjka spomina za nov objekt, ti sistem vrže ven okno in napako da ni dovolj pomnilnika in program se sam zapre. Ali kako bi bilo mogoče to realizirati?
"Lotereya - naibolee točnyj sposob učeta količestva optimistov"

Gundolf ::

Če ti zmanjka openGL spomina, potem ti trenutni gl ukaz 'fail'a in če kličeš glGetError, boš dobil vrednost v smislu out_of_mem.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C++] vprašanja (strani: 1 2 3 4 5 6 7 8 9 )

Oddelek: Programiranje
44726481 (11027) aljazko1995
»

Kako gre to v Dev C++ ???

Oddelek: Programiranje
142271 (1742) bi0s
»

[C++] Linux

Oddelek: Programiranje
171880 (1300) CCfly
»

[C++] Problem z dedovanjem šablon (template inhieritance)

Oddelek: Programiranje
131546 (1424) Gundolf
»

DevC++ težava?

Oddelek: Programiranje
181618 (1486) Gundolf

Več podobnih tem