c++ - LocalAlloc Vs GlobalAlloc Vs malloc Vs nuevo
winapi heap-memory (2)
Extractos de la nueva noticia de Raymond Chen
En los días de Windows de 16 bits, la diferencia era significativa.
En Windows de 16 bits, se accedió a la memoria a través de valores denominados "selectores", cada uno de los cuales podría cubrir hasta 64K. Había un selector por defecto llamado "selector de datos"; Las operaciones en los llamados "punteros cercanos" se realizaron en relación con el selector de datos. Por ejemplo, si tenía un puntero p cercano cuyo valor era 0x1234 y su selector de datos era 0x012F, entonces cuando escribió * p, estaba accediendo a la memoria en 012F: 1234. (Cuando declaró un puntero, estaba casi por defecto. Tenía que decir FAR explícitamente si quería un puntero lejano).
Importante: los punteros cercanos siempre son relativos a un selector, generalmente el selector de datos.
La función GlobalAlloc asignó un selector que podría usarse para acceder a la cantidad de memoria que solicitó. Puede acceder a la memoria en ese selector con un "puntero lejano". Un "puntero lejano" es un selector combinado con un puntero cercano. (Recuerde que un puntero cercano es relativo a un selector; cuando combina el puntero cercano con un selector apropiado, obtiene un puntero lejano).
Cada instancia de un programa y DLL tiene su propio selector de datos, conocido como HINSTANCE. Por lo tanto, si tenía un puntero p cercano y accedió a él a través de * p desde un programa ejecutable, accedió a la memoria relativa a la HINSTANCIA de la instancia del programa. Si accedió a él desde una DLL, obtuvo memoria relativa a la HINSTANCIA de su DLL.
Por lo tanto, en Windows de 16 bits, las funciones LocalAlloc y GlobalAlloc eran completamente diferentes. LocalAlloc devolvió un puntero cercano, mientras que GlobalAlloc devolvió un selector.
Los punteros que pretendía pasar entre los módulos tenían que estar en forma de "punteros lejanos" porque cada módulo tiene un selector predeterminado diferente. Si quería transferir la propiedad de la memoria a otro módulo, tenía que usar GlobalAlloc ya que eso le permitía al destinatario llamar a GlobalFree para liberarlo.
Incluso en Win32, debe tener cuidado de no confundir el montón local con el montón global. La memoria asignada de uno no puede liberarse en el otro. Toda la rareza acerca de los punteros cercanos y lejanos desapareció con la transición a Win32. Pero las funciones del montón local y las funciones del montón global son, sin embargo, dos interfaces de montón distintas.
Además, el link especificado por usted claramente dice que,
A partir de Windows de 32 bits, GlobalAlloc y LocalAlloc se implementan como funciones de envoltura que llaman a HeapAlloc utilizando un identificador del montón predeterminado del proceso, y se puede indicar a HeapAlloc que genere una excepción si no se puede asignar la memoria, una capacidad no disponible con LocalAlloc.
Para su confusión sobre malloc vs new , la respuesta de Billy ONeal lo resume con bastante claridad.
Por la diferencia entre malloc y HeapAlloc , la respuesta combinada de David Heffernan y Luis Miguel Huapaya da la solución perfecta:
-
malloc
es portátil, parte de la norma.malloc
(y otras funciones del montón de tiempo de ejecución de C) son dependientes del módulo, lo que significa que si llama amalloc
en el código de un módulo (es decir, una DLL), debería llamarfree
dentro del código del mismo módulo o podría sufrir un montón bastante malo corrupción. -
HeapAlloc
no es portátil, es una función API de Windows. El uso deHeapAlloc
conGetProcessHeap
lugar demalloc
, incluida la sobrecarga de operadoresnew
y dedelete
para utilizarlos, le permite pasar objetos asignados dinámicamente entre módulos y no tiene que preocuparse por la corrupción de la memoria si la memoria está asignada en el código de un módulo y liberada en el código de otro módulo una vez que el puntero a un bloque de memoria se ha pasado a un módulo externo.
He buscado esto en varios enlaces, pero aún persisten las dudas.
No entiendo la diferencia entre LocalAlloc
vs GlobalAlloc
vs malloc
vs new
para la asignación de memoria.
He pasado por este enlace de MSDN:
Comparación de los métodos de asignación de memoria
Por favor explique la siguiente declaración:
La función malloc tiene la desventaja de ser dependiente del tiempo de ejecución. El nuevo operador tiene la desventaja de ser dependiente del compilador y del idioma
GlobalAlloc
y LocalAlloc
son funciones antiguas de la era de 16 bits. La diferencia fue que a veces tenía que poder asignar memoria solo utilizada en su segmento (que usaba punteros cercanos), y en ocasiones necesitaba asignar memoria para compartirla con otros procesos y segmentos del sistema. Hoy en día, estos muchachos remiten de alguna forma u otra a las funciones de HeapXxx, como HeapAlloc
. Si está escribiendo un código nuevo y necesita evitar vincularse con el tiempo de ejecución de C, debe usar las funciones HeapXxx en su lugar. Por supuesto, si llama a cualquiera de estos, su programa solo se compilará y ejecutará en Windows.
malloc
es "dependiente del tiempo de ejecución", ya que su uso requiere que se enlace con el tiempo de ejecución de C (CRT). El CRT es la biblioteca que contiene todas las demás funciones estándar de la biblioteca C, como printf
o qsort
. Puede escribir un programa simple de API de Win32 sin vincularse con esto (pero honestamente no puedo ver por qué querría hacer eso en software real).
new
depende del compilador y del lenguaje, ya que requieren un compilador que pueda compilar C ++. (Y generalmente se implementa lo new
en términos de malloc
, por lo que probablemente también se requiera el uso de CRT)