Memoria
GLib envuelve el estándar malloc()
y free()
con sus propias variantes g_
, g_malloc()
y g_free()
, que se muestran en el Listado. Estos son agradables de varias maneras pequeñas:
-
g_malloc()
siempre devuelve ungpointer
, nunca unchar *
, por lo que no es necesario emitir el valor de retorno. -
g_malloc()
aborta el programa si elmalloc()
subyacente falla, por lo que no tiene que buscar un valor devueltoNULL
. -
g_malloc()
maneja con gracia unsize
de0
, devolviendoNULL
. -
g_free()
ignorará cualquier punteroNULL
que le pase.
📌 Nota: Antes del estándar ANSI/ISO C, el tipo de puntero genérico
void *
no existía ymalloc()
devolvía un valorchar *
. Actualmente,malloc()
devuelve un tipovoid *
(que es lo mismo quegpointer
) yvoid *
permite conversiones de puntero implícitas en C. Lanzando el valor de retorno demalloc()
es necesario si: el desarrollador quiere admitir compiladores antiguos; o si el desarrollador piensa que una conversión explícita aclara el código; o si se usa un compilador de C++, porque en C++ se requiere una conversión del tipovoid *
.
#include <glib.h>
gpointer g_malloc (gsize n_bytes);
void g_free (gpointer mem);
gpointer g_realloc (gpointer mem, gsize n_bytes);
gpointer g_memdup (gconstpointer mem, guint n_bytes);
Listado: Asignación de memoria GLib.
Es importante hacer coincidir g_malloc()
con g_free()
, malloc()
simple con free()
y si estás usando C++ new
con delete
. De lo contrario, pueden suceder comportamientos no esperados, ya que estos asignadores pueden usar diferentes grupos de memoria (y new
/delete
llama a constructores y destructores).
Por supuesto, hay un g_realloc()
equivalente a realloc()
. También hay un conveniente g_malloc0()
que llena la memoria asignada con ceros, y g_memdup()
que devuelve una copia de n_bytes
bytes comenzando en mem
. g_realloc()
y g_malloc0()
aceptarán ambos un tamaño de 0, por coherencia con g_malloc()
. Sin embargo, g_memdup()
no lo hará.
Si no es obvio: g_malloc0()
llena la memoria sin procesar con bits no configurados, no el valor 0 para cualquier tipo que pretenda poner allí. De vez en cuando, alguien espera obtener una matriz de números de coma flotante inicializados en 0.0; no se garantiza que funcione de forma portátil.
Por último, existen macros de asignación con reconocimiento de tipos, que se muestran en el Listado. El argumento type
para cada uno de estos es el nombre de un tipo, y el argumento count
es el número de bloques de tamaño type
a asignar. Estas macros le ahorran algo de escritura y multiplicación y, por lo tanto, son menos propensas a errores. Se lanzan automáticamente al tipo de puntero de destino, por lo que intentar asignar la memoria asignada al tipo de puntero incorrecto debería activar una advertencia del compilador. (Si tiene las advertencias activadas, ¡como debería hacerlo un programador responsable!)
#include <glib.h>
g_new (type, count);
g_new0 (type, count);
g_renew (type, mem, count);
Listado: Macros de asignación.