В чем разница между xmalloc()
и malloc()
для распределения памяти?
Есть ли какой-либо способ использования xmalloc()
?
В чем разница между xmalloc и malloc?
Ответ 1
xmalloc()
- это нестандартная функция, которая имеет девиз успеха или смерти. Если ему не удастся выделить память, она завершит вашу программу и выведет сообщение об ошибке на stderr
.
Само распределение не отличается; только поведение в случае, когда память не может быть выделена, отличается.
Используйте malloc()
, поскольку он более дружелюбный и стандартный.
Ответ 2
xmalloc
не входит в стандартную библиотеку. Обычно это имя очень вредной функции для ленивых программистов, которые распространены в большинстве программ GNU, которые вызывают abort
, если malloc
терпит неудачу. В зависимости от программы/библиотеки он также может преобразовать malloc(0)
в malloc(1)
, чтобы гарантировать, что xmalloc(0)
возвращает уникальный указатель.
В любом случае, abort
ing при ошибке malloc
очень плохое поведение, особенно для кода библиотеки. Одним из самых печально известных примеров является GMP (библиотека арифметических вычислений GNU), которая прерывает вызывающую программу всякий раз, когда у нее заканчивается нехватка памяти для вычисления.
Корректный код на уровне библиотеки должен всегда обрабатывать сбои распределения, резервируя любую частично выполненную операцию, которая была в середине, и возвращает код ошибки вызывающему. Затем вызывающая программа может решить, что делать, что, вероятно, потребует сохранения важных данных.
Ответ 3
Как уже упоминалось, верно, что xmalloc
очень часто реализуется как функция-обертка, которая вызывает поставляемую ОС malloc
и слепо вызывает abort
или exit
, если она терпит неудачу. Однако многие проекты содержат функцию xmalloc
, которая пытается сохранить состояние приложения перед выходом (см., Например, neovim).
Лично я думаю о xmalloc
как о конкретном расширенном malloc
для проекта, а не о выходе malloc
. Хотя я не помню, чтобы когда-либо видел версию, которая не вызывала вызов abort
или exit
, некоторые из них делают намного больше.
Итак, ответ на вопрос "Какая разница между xmalloc
и malloc
: это зависит. xmalloc
- это нестандартная, специфичная для проекта функция, поэтому она может вообще что-то делать. Конечно, нужно знать код.
Ответ 4
примитивный пример xmalloc.c в K & R C
#include <stdio.h>
extern char *malloc ();
void *
xmalloc (size)
unsigned size;
{
void *new_mem = (void *) malloc (size);
if (new_mem == NULL)
{
fprintf (stderr, "fatal: memory exhausted (xmalloc of %u bytes).\n", size);
exit (-1);
}
return new_mem;
}
то в заголовке кода (раньше) вы помещаете
#define malloc(m) xmalloc(m)
чтобы спокойно переписать источник перед компиляцией. (вы можете увидеть перезаписанный код, вызвав препроцессор C напрямую и сохранение вывода. )
если сбой вашей программы не то, что вы хотите, вы можете сделать что-то другое
- Использовать сборщик мусора
- измените свой код на меньший объем памяти
- имеет код проверки ошибок в вашей программе, чтобы обработать Out of Memory или другую ошибку распределения изящно.
Пользователям не нравится потерять свои данные во встроенную команду сбоя в своей программе.
Ответ 5
xmalloc
является частью libiberty https://gcc.gnu.org/onlinedocs/libiberty/index.html, который является библиотекой GNU utils.
malloc
- ANSI C.
xmalloc
часто включается в источник во многих важных проектах GNU, включая GCC и Binutils, оба из которых используют его много. Но также возможно построить его как динамическую библиотеку для использования в ваших программах. Например. Ubuntu имеет пакет libiberty-dev
.
xmalloc
документируется по адресу https://gcc.gnu.org/onlinedocs/libiberty/Functions.html, а в GCC 5.2.0 реализовано на libiberty/xmalloc.c
PTR
xmalloc (size_t size)
{
PTR newmem;
if (size == 0)
size = 1;
newmem = malloc (size);
if (!newmem)
xmalloc_failed (size);
return (newmem);
}
void
xmalloc_failed (size_t size)
{
#ifdef HAVE_SBRK
extern char **environ;
size_t allocated;
if (first_break != NULL)
allocated = (char *) sbrk (0) - first_break;
else
allocated = (char *) sbrk (0) - (char *) &environ;
fprintf (stderr,
"\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
name, *name ? ": " : "",
(unsigned long) size, (unsigned long) allocated);
#else /* HAVE_SBRK */
fprintf (stderr,
"\n%s%sout of memory allocating %lu bytes\n",
name, *name ? ": " : "",
(unsigned long) size);
#endif /* HAVE_SBRK */
xexit (1);
}
/* This variable is set by xatexit if it is called. This way, xmalloc
doesn't drag xatexit into the link. */
void (*_xexit_cleanup) (void);
void
xexit (int code)
{
if (_xexit_cleanup != NULL)
(*_xexit_cleanup) ();
exit (code);
}
Что, как упоминалось выше, довольно просто:
- попробуйте
malloc
- если он не работает
- выводить сообщения об ошибках
- вызов
exit
Ответ 6
Я видел xmalloc во время работы над IBM AIX. xmalloc - это служба ядра, предоставляемая AIX.
Ничто не может объяснить функцию лучше, чем функция man-страница, на мой взгляд. Поэтому я вставляю нижеследующие данные с man-страницы
Назначение: выделяет память.
Синтаксис:
caddr_t xmalloc (размер, выравнивание, куча)
Параметры:
size: Указывает количество выделенных байтов.
align: указывает характеристики выравнивания для выделенной памяти.
heap: Указывает адрес кучи, из которой должна быть выделена память.
Описание:
Служба ядра xmalloc выделяет область памяти из кучи, заданной параметром кучи. Эта область - это количество байтов в длине, указанное параметром размера, и выравнивается на границе байта, заданной параметром align. Параметр align является фактически базой 2 базы требуемой границы адреса. Например, выравнивающее значение из 4 запросов на выравнивание выделенной области на границе 2 ^ 4 (16) байтов.
Существует множество куч, предоставляемых ядром для использования расширениями ядра. Двумя ядрами ядра являются kernel_heap и pinned_heap. Расширения ядра должны использовать значение kernel_heap при распределении памяти, которая не привязана, и должна использовать значение pinned_heap при распределении памяти, которая всегда должна быть закреплена или закреплена в течение длительных периодов времени. При выделении из кучи pinned_heap служба ядра xmalloc связывает память перед успешным возвратом. Службы pin и unpin kernel должны использоваться для вывода и отключения памяти из кучи kernel_heap, когда память должна быть привязана только к ограниченному количеству времени. Перед освобождением памяти из кучи kernel_heap необходимо отключить. Память из кучи pinned_heap не должна быть удалена.
Если вам интересно узнать больше об этой функции, посетите следующую ссылку: Поддержка IBM AIX