glib обертывает стандартные "malloc()" и "free()" своими "g_"-вариантами: "g_malloc()" и "g_free()", показанными в списке функций 2..1. Они привлекательны по нескольким параметрам:
В дополнение к этим небольшим удобствам, "g_malloc()" и "g_free()" могут поддерживать различные типы отладки и профилировки использования памяти. Если вы укажете параметр "-enable-mem-check" для скрипта configure библиотеки glib, скомпилированный "g_free()" будет вас предупреждать всякий раз, когда вы освобождаете один и тот же указатель дважды. Опция "-enable-mem-profile" разрешает код, которые ведет статистику использования памяти; когда вы вызываете "g_mem_profile()", она печатается на консоль. Наконец, вы можете определить "USE_DMALLOC", и тогда функции для работы с памятью из glib будут использовать MALLOC() и другие макросы для отладки, доступные в dmalloc.h на некоторых платформах.
gpointer g_malloc(gulong size)
void g_free(gpointer mem)
gpointer g_realloc(gpointer mem, gulong size)
gpointer g_memdup(gconstpointer mem, guint bytesize)
Очень важно сопоставить "g_malloc()"'у "g_free()", а простому "malloc()"'у -- "free()", и (если вы используете C++) вызову new -- вызов delete. Иначе может случиться страшное, так как эти функции могут использовать различные пулы памяти (а new/delete вызывают к тому же конструкторы и деструкторы).
Конечно, есть "g_realloc()", эквивалентный "realloc()". Есть также удобный "g_malloc0()", который заполняет распределенную память нулями, и "g_memdup()", который возвращает копию размером bytesize байт, начинающуюся в mem. "g_realloc()" и "g_malloc0()" -- оба понимают size равный 0 для совместимости с "g_malloc()". Однако "g_memdup()" -- нет.
Если это неочевидно: "g_malloc0()" заполняет исходную область памяти неустановленными битами, а не значением 0, независимо от типа. Некоторые ожидают получить массив чисел с плавающей точкой, проинициализированный значением 0.0; это не будет работать.
Наконец, есть макросы распределения памяти, знающие о типах, показанные в списке макросов 2..5. Аргумент type каждого из них -- это имя типа, а аргумент count -- число блоков указанного типа, которые надо распределить. Эти макросы сэкономят вам некоторое количество нажатий клавиш и умножений, и поэтому менее склонны к ошибкам. Они автоматически преобразуют к результирующему типу, поэтому попытка присвоения рапределенной памяти неправильному типу указателя, вызовет предупреждение компилятора. (Если вы включили предупреждения, как должны делать ответственные программисты!)
g_new(type, count)
g_new0(type, count)
g_renew(type, mem, count)