PDA

Visualizza la versione completa : [C] Saturazione dell'heap e accesso alla memoria


Ed_Bunker
26-11-2007, 11:08
Ho fatto uno stupido programmino in C che non faceva altro che chiamare in continuazione la funzione malloc in modo da allocare dinamicamente lo spazio per una certa struct nell'heap.
La mia intenzione era quella di "stampare" il totale di mem allocata nel momento in cui il valore di ritorno della malloc era NULL e errno valeva ENOMEM.

Cio' pero' non e' accaduto.
Ad un certo punto l'app e' stata killata dal s.o. ed a video (Su shell) e' comparso il messaggio "killed".

In base a cosa il processo e' stato killato ?
Esiste un numero di bytes massimo che ciascun processo puo' allocare sull'heap ?

Rinfrescatemi bene la mem.. perche ne' ho bisogno...
:berto:

oregon
26-11-2007, 11:22
Con Linux, in una situazione di fallita allocazione di memoria, interviene un processo (OOM killer) che termina il processo che ha fatto la richiesta di memoria.

Questo processo non c'e' in Windows.

Ed_Bunker
26-11-2007, 11:31
Ok, cio' che volevo sapere e' se a priori ciascun processo puo' sapere quanto spazio poter allocare sull'heap ovvero e di conseguenza quanto "memory leak" si puo' in teoria permettere.

Ho notato, poi, che dopo aver fatto una free il puntatore e' ancora valido ed e' possibile riassegnare la variabile che esso punta.

Questo vale "sempre" o come mi sembra di capire dal man dipende dalla gestione della mem da parte del s.o. ?

Questo il banale codice di esempio:



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

struct prova
{
int val;
struct prova *next;
};

int main()
{

/*Alloca*/
struct prova* first = malloc(sizeof(struct prova));

/*Assegna*/
first->val = 5;
first->next = NULL;

printf ("Before free: %d\n", first->val);

/*Libera*/
free(first);
printf ("After free: %d\n", first->val);

/*Riassegna*/
first->val = 10;
printf ("After an assignment post-free: %d\n", first->val);

return(0);
}


Se invece di fare la free effettuo un assegnamento del puntatore a NULL allora nell'istruzione successiva di assegnamento ottengo, "giustamente", un SIGSEGV.

oregon
26-11-2007, 11:51
Dopo la free il puntatore NON e' valido. Fai attenzione.

Ed_Bunker
26-11-2007, 12:14
Originariamente inviato da oregon
Dopo la free il puntatore NON e' valido. Fai attenzione.
Devo essermi spiegato male...

SO che dopo la free il puntatore NON DOVREBBE essere valido.
Eppure quel programma NON GENERA segmentation fault.

Nonostante io faccia un allocazione ed un riferimento al valore puntato DOPO aver fatto la free.

Cio' che volevo sapere e' se questo e' un comportamento che dipende dalla "particolare" gestione della memoria da parte del s.o. che si occupa di "recuperare" la memoria "freed" come e quando gli pare.

oregon
26-11-2007, 12:18
Dopo una free il valore del puntatore non e' piu' LOGICAMENTE valido.

Ovvero, subito dopo la free, probabilmente, puo' essere ancora utilizzato perche' la memoria a cui punta e' ancora mappata nel processo ma NON e' cosi' in generale perche' il sistema operativo puo' decidere IN QUALSIASI MOMENTO di rendere NON VALIDA quella porzione di memoria e il relativo puntatore.

In generale, dopo la free, e' bene porre il puntatore = NULL per evitare questo tipo di problemi.

Ed_Bunker
26-11-2007, 12:38
Ecco ora ci siamo.

Come mi sembrava di aver "presunto" dipende dalla particolare gestione del s.o.

Cio' che mi "sorprende" non e' il fatto che la memoria gia' "liberata" sia ancora accessibile quanto, invece, che sia ancora modificabile.

Il che pensavo diventasse impossibile non appena veniva effettuata la free.

pallinopinco
26-11-2007, 12:55
Stiamo parlando di dangling pointers (http://en.wikipedia.org/wiki/Dangling_pointer), o sbaglio? :)

oregon
26-11-2007, 13:02
Originariamente inviato da pallinopinco
Stiamo parlando di dangling pointers

Esatto ...


Originariamente inviato da Ed_Bunker
Il che pensavo diventasse impossibile non appena veniva effettuata la free.

No ... assolutamente ... la free indica soltanto al SO (scrivendo in strutture collegate al processo) che quell'area di memoria NON e' piu' posseduta dal processo, ma non fa nulla relativamente alla presenza della pagina in memoria o alla sua possibile utilizzazione in lettura/scrittura (di questo se ne occupa il sistema operativo quando si accorge che e' necessario "recuperare" pagine allocate per altri processi che ne fanno richiesta).

Ed_Bunker
26-11-2007, 16:39
In "sostanza" e' come dire al gestore della mem: quella parte di mem non mi serve piu', fanne cio' che vuoi ?!?
:D

Loading