Uvolňování paměti – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Uvolňování paměti – C / C++ – Fórum – Programujte.comUvolňování paměti – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Michal
~ Anonymní uživatel
624 příspěvků
22. 8. 2012   #1
-
0
-

 Ahoj,
chtěl bych si nechat poradit ohledně alokace/uvolňování paměti v C++. Už při takhle jednoduchym programu, kde jen naalokuju paměť pro 2D pole a hned ji zase uvolňuji, mi program těsně před koncem pořád zabírá téměř 2MB paměti. Nevíte proč?

V tomhle případě by to nebyl problém, ale já to potřebuju na hlubokou rekurzi, kde mi tyhle "zbytky" po chvíli vyžerou paměť a ukončí program.

Díky, Michal

#include <stdio.h>
#include <stdlib.h>

	int ** M;
	int rozmer;
	int i, j;

int main(void){

	rozmer = 10000;

	M = (int **) calloc(rozmer, (sizeof(int *)));
	
	for (i = 0; i < rozmer; i++) {
		M[i] = (int *) calloc(rozmer, (sizeof(int)));
	}

	for ( i = 0; i < rozmer; i++){
		free(M[i]);
		M[i] = NULL;
	}
	free(M);

	return 0;

}
Nahlásit jako SPAM
IP: 90.181.50.–
Reklama
Reklama
vitamin+8
Grafoman
22. 8. 2012   #2
-
0
-

Nemáš tam žiadne memory leaky. Ani valgrind nič nenašiel. Samotné inštrukcie a lokálny stack a rôzne iné veci zaberajú dosť miesta.

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
KIIV+42
God of flame
22. 8. 2012   #3
-
0
-

kdyz delas v c++ proc nepouzijes vector?

mimochodem nevim jak ve windowsu, ale pod linuxem se zvetsuje velikost datasegmentu, az kdyz je potreba pomoci prikazu brk() (automaticky kdyz je potreba vic pameti nez program ma) - a ted to zajimavejsi, program ji zabira i po uvolneni teto alokace (muze ji akorat znovuvyuzit, ale jinak zustava fyzicky zabrana v ram tak jak tak)

kdyz nechas ten program spustenej (treba pomoci dlouhyho sleep) tak muzes mrknout co je v procesu jak namapovane pomoci   pmap PID  (opet linux - win netusim jestli ma)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Michal
~ Anonymní uživatel
624 příspěvků
22. 8. 2012   #4
-
0
-

To Vitamin:
Ale program před alokací zabírá cca 300kB, v žádném případě ne 2MB. A jak říkám, když podobných alokací/uvolnění provedu hodně, tak paměť pořád roste.

To KIIV:
V C++ delam tak trochu omylem, moc v něm neumím, ale vector si vygooglím. :) Jen mi to přišlo unáhlené hledat jiné řešení, když tohle by mělo perfektně fungovat.
Zapomněl jsem tedy napsat, že dělám na win 7 64 bit a ten je na tom o dost hůře, co se týče utilit na zkoumání alokované paměti. Problém je, že se ta pamět znova nevyužije, tedy aspoň ne celá. Například jsem celý program obalil cyklem, provedl jsem ho 10 resp. 100 a zabraná paměť vzrostla na 3MB resp. 5MB.

Nahlásit jako SPAM
IP: 90.181.50.–
ingiraxo+15
Grafoman
22. 8. 2012   #5
-
0
-

obávám se, že těch 2.2MB po dealokaci se nezbavíš (možná nějakou winAPI funkcí co násilně  čistí pamět)... po dealokaci se pamět uvolní tak, že je možný jí přepsat, takže se chová jako volný místo i když to ukazuje víc, než při spuštění programu... resp. to, co psal KIIV

jinak kdyz děláš v C++, tak nevim proč nepoužiješ syntax z C++... sice by byl vektor lepší, ale klasický 2D pole máš jako: 

#include <iostream>
using namespace std;

int main()
{
	const int rozmer = 10000;

	cin.get(); // cca 650KB

	int** pole = new int*[rozmer];

	for (int i = 0; i < rozmer; i++)
	{
		*(pole + i) = new int[rozmer];
	}

	cin.get(); // 390.6MB + cca 2.5MB

	for (int i = 0; i < rozmer; i++)
	{
		delete *(pole + i);
	}
	delete pole;

	cin.get(); // cca 2,2MB
	return 0;
}
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
vitamin+8
Grafoman
22. 8. 2012   #6
-
0
-

#3 KIIV

pmap -x 23875
23875:   ./test
Address           Kbytes     RSS   Dirty Mode   Mapping
0000000000400000       0       4       4 r-x--  test  //1
0000000000600000       0       4       4 r----  test  //2
0000000000601000       0       4       4 rw---  test  //3
00000000009e7000       0     208     208 rw---    [ anon ]
00007fd7d3e0e000       0     296       0 r-x--  libc-2.15.so
00007fd7d3fc1000       0       0       0 -----  libc-2.15.so
00007fd7d41c0000       0      16      16 r----  libc-2.15.so
00007fd7d41c4000       0       8       8 rw---  libc-2.15.so
00007fd7d41c6000       0      12      12 rw---    [ anon ]
00007fd7d41cb000       0     108       0 r-x--  ld-2.15.so
00007fd7d43cd000       0      12      12 rw---    [ anon ]
00007fd7d43e9000       0      12      12 rw---    [ anon ]
00007fd7d43ed000       0       4       4 r----  ld-2.15.so
00007fd7d43ee000       0       8       8 rw---  ld-2.15.so
00007fff2f5b4000       0      12      12 rw---    [ stack ]
00007fff2f5e8000       0       4       0 r-x--    [ anon ]
ffffffffff600000       0       0       0 r-x--    [ anon ]
----------------  ------  ------  ------
total kB            4364     712     304

Chápem to správne, že na 1. riadku je pamäť pre funkcie a konštanty a na 3. riadku sú globalne premenné?

Čo sú riadky s [ anon ] ?

[ stack ]  toto vyzerá na lokálny stack.

Čo sa ukladá do pamäte na 2. riadku?

edit:  tak [ anon ] bude asi dynamicky alokovaná pamäť (aspoň prvý riadok s anon, čo sú zvyšné? )

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
KIIV+42
God of flame
22. 8. 2012   #7
-
+1
-
Zajímavé

anon sou nejaky nabrany bloky...  jedno z nich je taky heap...

treba kdyz sem to vystihl nekde v prubehu programu:

0000000000400000      4K r-x--  /home/test/test_alokace/a.out
0000000000600000      4K r----  /home/test/test_alokace/a.out
0000000000601000      4K rw---  /home/test/test_alokace/a.out
0000000000e06000 307596K rw---    [ anon ]
00007fdf88260000   1576K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so
00007fdf883ea000   2048K -----  /lib/x86_64-linux-gnu/libc-2.13.so
00007fdf885ea000     16K r----  /lib/x86_64-linux-gnu/libc-2.13.so
00007fdf885ee000      4K rw---  /lib/x86_64-linux-gnu/libc-2.13.so
00007fdf885ef000     24K rw---    [ anon ]
00007fdf885f5000     84K r-x--  /lib/x86_64-linux-gnu/libgcc_s.so.1
00007fdf8860a000   2044K -----  /lib/x86_64-linux-gnu/libgcc_s.so.1
00007fdf88809000      4K r----  /lib/x86_64-linux-gnu/libgcc_s.so.1
00007fdf8880a000      4K rw---  /lib/x86_64-linux-gnu/libgcc_s.so.1
00007fdf8880b000    528K r-x--  /lib/x86_64-linux-gnu/libm-2.13.so
00007fdf8888f000   2044K -----  /lib/x86_64-linux-gnu/libm-2.13.so
00007fdf88a8e000      4K r----  /lib/x86_64-linux-gnu/libm-2.13.so
00007fdf88a8f000      4K rw---  /lib/x86_64-linux-gnu/libm-2.13.so
00007fdf88a90000    928K r-x--  /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14
00007fdf88b78000   2044K -----  /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14
00007fdf88d77000     32K r----  /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14
00007fdf88d7f000      8K rw---  /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14
00007fdf88d81000     84K rw---    [ anon ]
00007fdf88d96000    132K r-x--  /lib/x86_64-linux-gnu/ld-2.13.so
00007fdf88f80000     20K rw---    [ anon ]
00007fdf88fb4000      8K rw---    [ anon ]
00007fdf88fb6000      4K r----  /lib/x86_64-linux-gnu/ld-2.13.so
00007fdf88fb7000      8K rw---  /lib/x86_64-linux-gnu/ld-2.13.so
00007fffcbd4e000    132K rw---    [ stack ]
00007fffcbdff000      4K r-x--    [ anon ]
ffffffffff600000      4K r-x--    [ anon ]
 total           319400K

co ma r tak se da cist... pokud to ma w tak i zapisovat... kdyz je tam  r-x tak je to code block

predpokladam ze zednotlivy anon sekce patri k libkam nebo programum co jsou pred nima

stack je samozrejme jasnej

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
22. 8. 2012   #8
-
0
-

kazdopadne se program zvetsil o cca 100kB at uz 100x opakovana alokace nebo 1000x

zkusil bych mozna i jinej kompilator..

+ jestli dela tydle alokace i v rekurzi tak se vubec nedivim ze to vyzere vsechnu pamet :D

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
22. 8. 2012   #9
-
0
-

#7 KIIV

Len nechápem prečo sú statické konštantné premenné uložené v r-x pamäti. Načo je tam potom tá r-- pamäť?

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
KIIV+42
God of flame
22. 8. 2012   #10
-
0
-

r-x to je samotny spustitelny kod... nikde jinde se nepovoli vykonavat instrukce (a hlavne se tam neda zapsat - hned to hodi SIGSEGV - tj. nemuzes si prepsat jen tak kod programu)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV+42
God of flame
22. 8. 2012   #11
-
0
-

mimo to je lepsi pouzivat jednorozmerne pole ... neco jako

    vector<int> test;
    test.resize(rozmer*rozmer); // zvetsit pole a take se prvky inicializuji


    cout << "velikost pole: " << test.size() << endl;

// pristup k prvku
    test[ x+y*rozmer ] = 1; // a podobne
Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ondra.holub+1
Stálý člen
22. 8. 2012   #12
-
0
-

#5 ingiraxo
Místo delete je tady krajně vhodné použít delete[].

Nahlásit jako SPAM
IP: 212.96.189.–
KIIV+42
God of flame
22. 8. 2012   #13
-
0
-

#12 ondra.holub
krom toho jak sam Stroustrup naznacoval v prednasce o c++11, nepouzivat vubec takovy saskarny jako new/delete nezabaleny treba ve tride

v pulce alokaci mu to hodi vyjimku a je konec... (sice se o to postara system ale co soubory nebo cokoliv jinyho co by se melo ukoncit)

Nahlásit jako SPAM
IP: 78.45.44.–
Program vždy dělá to co naprogramujete, ne to co chcete...
ingiraxo+15
Grafoman
22. 8. 2012   #14
-
0
-

#12 ondra.holub
jo, ale delete[], který by mělo uvolnit pole, tak se tak nestane, aspon ne v tom pripade jak jsem psal ten kus kodu... pri delete[] mi v pameti stale zustalo 392MB O_o

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
KIIV+42
God of flame
22. 8. 2012   #15
-
0
-

#14 ingiraxo
u me to funguje v pohode... vsechno se krasne uvolni s delete []  - kdo vi co pouzivas za prekladac..

Nahlásit jako SPAM
IP: 78.45.44.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 246 hostů

Podobná vlákna

Uvolnovani pameti — založil Aaron

Uvolňování paměti — založil petr

Nedostatek paměti — založil ProgDan

Uvolneni pameti — založil BigBear

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý