2010-01-29 14 views
6

In Win32 per incollare i dati negli appunti devo chiamare GlobalAlloc(), quindi GlobalLock() per ottenere un puntatore, quindi copiare i dati, quindi chiamare GlobalUnlock() e SetClipboardData().Cosa succede se chiamo GlobalLock(), quindi non riesco a chiamare GlobalUnlock()?

Se il codice è in C++ un'eccezione potrebbe essere gettati tra le chiamate al GlobalLock() e GlobalUnlock() e se non mi prendo cura di questo GlobalUnlock() non sarà chiamato.

Si tratta di un problema? Cosa succede esattamente se chiamo GlobalLock() e per qualsiasi motivo salta una chiamata GlobalUnlock()?

risposta

9

La domanda non riguarda solo se o non si chiama GlobalUnlock(). È necessario chiamare GlobalUnlock() e GlobalFree(). Entrambi devono essere richiamati per liberare la memoria allocata:

HGLOBAL hdl = NULL; 
void *ptr = NULL 

    try { 
    hdl = GlobalAlloc(); 
    ptr = GlobalLock(hdl); 

    // etc... 
    GlobalUnlock(hdl); 
    ptr = NULL; 
    SetClipboardData(..., hdl); 
    } 
    catch (...) { 
    if(ptr) 
     GlobalUnlock(hdl); 
    if(hdl) 
     GlobalFree(hdl); 
    throw; 
    } 

La perdita sarebbe estesa all'applicazione. Quando si esce da un'applicazione Windows, tutta la memoria privata allocata viene rilasciata automaticamente

+1

No, non si deve chiamare GlobalFree() se i dati vengono incollati negli Appunti: la proprietà viene passata al clipborad e la memoria verrà rilasciata una volta dopo. – sharptooth

+1

Sì, hai ragione, se la chiamata a SetClipboardData è stata eseguita correttamente. Altrimenti, devi chiamare entrambi. Post modificato di conseguenza. –

9

Più che avreste sempre voluto sapere (davvero) su GlobalLock(), per gentile concessione di Raymond Chen:

Sto marcando questo wiki della comunità perché in realtà non so se questi articoli rispondono alla tua domanda. Ma probabilmente valgono la pena di attraversare, almeno per un minimo.

Tuttavia, un modo per gestire il problema relativo alla gestione di GlobalUnlock() in presenza di eccezioni consiste nell'utilizzare una classe RAII per gestire le chiamate GlobalLock()/GlobalUnlock().

Problemi correlati