Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698

    [C] Malloc/Free, memoria non rilasciata

    Non so se questo tipo di problema può essere catalogato come memory leak, ad ogni modo gli assomiglia molto: una mia funzione alloca con calloc un vettore di puntatori (a struct). Faccio quello che devo fare, alla fine della funzione libero tutto con una free.

    codice:
            DATA * mat[MAX];
    	
    	if (cond) {
    
    	
    		// ...
    
    
    	} else {
    
    
    		mat[0] = (DATA *)calloc(1,sizeof(DATA));
    		mat[0]->wp = src;
    		
    		for (j=1,i=next; i<n; i++,j++)
    		{
    			mat[j] = (DATA*) calloc(1,sizeof(DATA));
    			mat[j]->wp = w[i];
    		}
    
    		n_mat = n;
    		
    		if ( F (n_mat,mat) ) {
    			_err(ERR_F);
    		}
    		
    		for (i=0; i<n_mat; i++)
    		{
    			
    			if (!i)  continue;
    				
    			cons += mat[i]->cons;
    					
    		
    		}
    
    		*cdst = cons ;
    		*cwp = mat[1]->cons ;
    
    		for (j=0,i=next; i<n; i++,j++) free(mat[j]);
    		
    
    	}
    Praticamente (lo vedo anche da task manager) la memoria che viene allocata da questa funzione non viene rilasciata nella stessa quantità con cui è allocata; ovvero vedo un aumento costante di memoria.

    Devo usare l'allocazione dinamica perchè la funzione F vuole un array di puntatori..altrimenti dichiarerei un vettore statico e tanti cari saluti.

    Ho fatto varie ricerche e la questione sembra essere imputabile al fatto che il sistema operativo (WIN32 in questo caso) rilascia la memoria per utilizzi futuri del programma che l'ha allocata, e non la rende di nuovo disponibile a se stesso, con lo scopo di ottimizzare le operazioni di allocazione/deallocazione. Bene.

    Il problema è che la mia funzione viene invocata continuamente, ogni due secondi, da un applicazione esterna. Finchè l'utente non si stanca e stacca tutto, potenzialmente per un tempo pari a infinito. Dato che le macchine non hanno risorse infinite ( nel nostro caso, anzi, sono piuttosto limitate ), prima o poi il sistema si inchioda perchè non ha piu memoria disponibile.

    Ora, supponendo che il codice che ho scritto non contenga errori grossolani, cosa mi dovrei inventare per stabilizzare la memoria richiesta?

    Grazie dell'attenzione

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,468
    Che Windows ottimizzi la gestione della memoria disponibile per un processo (gestione del working set) è normalissimo.

    Per capire se c'e' veramente un problema di "memory leak" bisognerebbe fare alcune prove che, a distanza, non sono agevoli.

    Comunque, puoi controllare da Task Manager cosa succede alla memoria del processo quando ne minimizzi la finestra (se ne ha una).

    Per quanto riguarda il codice, non si nota (a prima vista) qualche problema.
    In realta', i cicli sono controllati dalla variabile i che parte da next e arriva ad n. Nulla sappiamo di queste due variabili ne' se la funzione F crea problemi al suo interno.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    No sono da escludere problemi legati agli indici ed alla funzione F perche ovviamente ho provato a far girare il tutto disabilitandola ed il problema persiste.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,468
    Ok, ma il tuo programma e' molto piu' di quelle linee che ci hai fatto vedere ...

    Chi assicura che il problema della memoria non rilasciata non sia da qualche altra parte?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    Beh in teoria nessuno
    In pratica, quello è tutto e solo il codice della funzione.

    Se il programma gira con cond=0, il problema non sussiste..percio sono relativamente sicuro non solo che il problema sia in quella funzione, ma anche che il problema sia nel ramo FALSE di quella if

    Sto facendo delle prove utilizzando le chiamate di sistema Heapxxx invece delle xalloc/free, appena finisco posto i risultati.

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    Allora allego questo test, per completezza, anche se non è servito a molto. Ha comunque evidenziato che xalloc e Heapxxx gestiscono la memoria in modi differenti.

    codice:
    #include <windows.h>
    #include <stdio.h>
    
    #define THE_BIG_ONE 10000
    #define MEMORY_MANAGER 1
    
    
    typedef struct 
    {
    	double x,y;
    
    } paramStruct;
    
    typedef struct 
    {
    	double x,y;
    	paramStruct p;
    
    } myStruct;
    
    
    
    
    int main (void)
    {
    	HANDLE hHeap;
    	SIZE_T size;
    	myStruct * arr[THE_BIG_ONE];
    	paramStruct p[THE_BIG_ONE];
    	int i;
    
    	hHeap = GetProcessHeap();
    
    	
    	for (;;)
    	{
    		for (i=0; i<THE_BIG_ONE; i++) 
    		{
    			if (MEMORY_MANAGER) arr[i] = (myStruct*)calloc(1,sizeof(myStruct));
    			else arr[i] = (myStruct*)HeapAlloc(hHeap,0x08,sizeof(myStruct));
    
    			arr[i]->p = p[i];
    		}
    
    		for (i=0; i<THE_BIG_ONE; i++) 
    		{
    			arr[i]->x = (double)time(0);
    			arr[i]->y = (double)time(0);
    			printf("%f %f\n",arr[i]->x,arr[i]->y);
    		}
    
    		for (i=0; i<THE_BIG_ONE; i++) 
    		{
    			if (MEMORY_MANAGER) free(arr[i]);
    			else HeapFree(hHeap,HEAP_NO_SERIALIZE,arr[i]);
    			
    		}
    
    		printf("Mem released\n");
    		//system("pause");
    	}
    
    	
    
    	
    }
    Cambiando il valore di MEMORY_MANAGER l'unica indicazione che ottengo è che allocare con xalloc riserva piu memoria di quella riservata con le Heapxxx. Però al momento del rilascio, la memoria viene restituita al sistema operativo (si vede da task manager).

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2003
    Messaggi
    698
    Chiedo venia.

    Effettivamente aveva ragione oregon, che ringrazio degli interventi, ed il problema stava, molto banalmente, nella gestione degli indici: infatti il ciclo for di deallocazione non teneva conto della allocazione fatta fuori ciclo (quella dell'elemento in posizione zero).

    Per questo motivo ad ogni invocazione rimaneva una cella dell'array allocata..che mi ciucciava la memoria. E' bastato aggiungere un minore uguale qui

    codice:
    for (j=0,i=next; i<=n; i++,j++) free(mat[j]);
    Voglio morire

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,468
    Originariamente inviato da Gil Mour
    Effettivamente aveva ragione oregon ... Voglio morire
    Vedi perche', molte volte, insisto su tante piccole cose, sembrando pedante e pignolo?

    Solo perche', negli anni, tutti questi piccoli intoppi mi sono gia' capitati ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.