Domanda

Considera questo caso:

dll = LoadDLL()
dll->do()

...
void do() {
    char *a = malloc(1024);
}
...

UnloadDLL(dll);

A questo punto, 1k allocato nella chiamata a malloc () sarà nuovamente disponibile per il processo host? La DLL si collega staticamente al CRT.

È stato utile?

Soluzione

No, non perdi.

Se si mescolano modelli di dll (statici, dinamici), si può finire con un errore di memoria se si alloca memoria in una dll, che si libera in un altro (o liberato nell'esempio)

Ciò significa che l'heap creato dal CRT collegato staticamente non è lo stesso heap del CRT di una DLL diversa.

Se ti collegassi con la versione dinamica del CRT, allora avresti una perdita poiché l'heap è condiviso tra tutti i CRT collegati in modo dinamico. Significa che dovresti sempre progettare le tue app in modo che utilizzino i CRT dinamici o assicurarti di non gestire mai la memoria oltre un limite di dll (ad esempio, se allochi memoria in una dll, fornisci sempre una routine per liberarla nella stessa dll)

Altri suggerimenti

  1. La memoria utilizzata da un processo monitorato dal sistema operativo è applicabile all'intero processo e non specifica per una DLL.

  2. La memoria viene data al programma in blocchi dal sistema operativo, chiamato heap

  3. I gestori di heap (malloc / new etc) suddividono ulteriormente i blocchi e lo distribuiscono al codice di richiesta.

  4. Solo quando viene allocato un nuovo heap il sistema operativo rileva un aumento della memoria.

  5. Quando una DLL è staticamente collegata alla libreria C Run time (CRT), una copia privata di CRT con le funzioni CRT invocate dal codice della DLL viene compilata e inserita nel file binario della DLL. Anche Malloc è incline a questo.

  6. Questa copia privata di malloc verrà invocata ogni volta che il codice presente all'interno della DLL collegata staticamente tenta di allocare memoria.

  7. Di conseguenza, un heap privato visibile solo a questa copia di malloc, viene acquisito dal sistema operativo da questo malloc e alloca la memoria richiesta dal codice all'interno di questo heap privato.

  8. Quando la DLL viene scaricata, scarica il suo heap privato e questa perdita non viene notata quando l'intero heap viene restituito al sistema operativo .

  9. Tuttavia, se la DLL è collegata dinamicamente, la memoria viene allocata da una singola versione condivisa di malloc, globale a tutto il codice collegato in modalità condivisa.

  10. La memoria allocata da questo malloc globale, proviene da un heap che è anche l'heap utilizzato per tutti gli altri codici collegati nella modalità dinamica aka aka e quindi è comune. Qualsiasi perdita da questo ammasso diventa quindi una perdita che influenza l'intero processo.

Modifica: aggiunte le descrizioni dello scenario di collegamento.

Non puoi dirlo. Ciò dipende dall'implementazione del CRT statico e dinamico. Può anche dipendere dalla dimensione dell'allocazione, in quanto vi sono CRT che inoltrano grandi allocazioni al sistema operativo, ma implementano il proprio heap per allocazioni di piccole dimensioni.

Il problema con una CRT che perde è ovviamente che perde. Il problema con un CRT che non perde è che l'eseguibile potrebbe ragionevolmente aspettarsi di usare la memoria, poiché la memoria mallocata dovrebbe rimanere utilizzabile fino a quando non viene chiamato free.

Da MSDN Potenziali errori nel passaggio di oggetti CRT attraverso i limiti delle DLL

  

Ogni copia della libreria CRT ha un   stato separato e distinto. Come tale,   Oggetti CRT come handle di file,   variabili di ambiente e locali sono   valido solo per la copia del CRT   dove questi oggetti sono allocati o   impostato. Quando una DLL e i suoi utenti utilizzano   diverse copie della libreria CRT,   non puoi passare questi oggetti CRT   oltre il limite della DLL e aspettarsi   per essere raccolti correttamente sul   dall'altra parte.

     

Inoltre, perché ogni copia del CRT   la biblioteca ha il suo gestore di heap,   allocare memoria in una libreria CRT   e passando il puntatore su una DLL   confine per essere liberato da un diverso   copia della libreria CRT è un potenziale   causa di corruzione dell'heap.

Spero che questo aiuti.

In realtà, la risposta contrassegnata non è corretta. Proprio così c'è una perdita. Mentre è tecnicamente fattibile per ogni dll implementare il proprio heap e liberarlo allo spegnimento, la maggior parte di "runtime" heap - statici o dinamici - sono wrapper attorno all'API heap del processo Win32.

A meno che uno non abbia prestato particolare attenzione a garantire che non sia così, la dll perderà l'allocazione per carico, eseguirà, scaricherà il ciclo.

Uno potrebbe fare un test e vedere se ci sono perdite di memoria. Esegui un semplice test 30 volte allocando 1 MB ogni volta. Dovresti capirlo abbastanza rapidamente.

Una cosa è certa. Se hai allocato memoria nella DLL, dovresti anche liberare quella memoria lì (nella DLL).

Ad esempio dovresti avere qualcosa del genere (pseudocodice semplice ma intuitivo):

dll = DllLoad();

ptr = dll->alloc();

dll->free(ptr);

DllUnload(dll);

Questo deve essere fatto perché la DLL ha un heap diverso rispetto al processo originale (che carica la dll).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top