What is the difference between xmalloc()
and malloc()
for memory allocation?
Is there any pro of using xmalloc()
?
xmalloc
is not part of the standard library. It's usually the name of a very harmful function for lazy programmers that's common in lots of GNU software, which calls abort
if malloc
fails. Depending on the program/library, it might also convert malloc(0)
into malloc(1)
to ensure that xmalloc(0)
returns a unique pointer.
In any case, abort
ing on malloc
failure is very very bad behavior, especially for library code. One of the most infamous examples is GMP (the GNU multiprecision arithmetic library), which aborts the calling program whenever it runs out of memory for a computation.
Correct library-level code should always handle allocation failures by backing out whatever partially-completed operation it was in the middle of and returning an error code to the caller. The calling program can then decide what to do, which will likely involve saving critical data.
xmalloc
is part of libiberty
https://gcc.gnu.org/onlinedocs/libiberty/index.html which is a GNU utils library.
malloc
is ANSI C.
xmalloc
is often included in-source in many important GNU projects, including GCC and Binutils, both of which use it a lot. But it is also possible to build it as a dynamic library to use in your programs. E.g. Ubuntu has the libiberty-dev
package.
xmalloc
is documented at: https://gcc.gnu.org/onlinedocs/libiberty/Functions.html and on GCC 5.2.0 it is implemented on 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);
}
Which as others mentioned, is pretty straightforward:
malloc
exit
As others have mentioned, it's true that xmalloc
is very often implemented as a wrapper function that invokes the OS-supplied malloc
and blindly calls abort
or exit
if it fails. However, many projects contain an xmalloc
function that tries to save application state before exiting (see, for example, neovim).
Personally, I think of xmalloc
as a kind of project-specific extended malloc
rather than an exiting malloc
. Though I don't recall ever seeing a version that didn't wind up calling abort
or exit
, some of them do a lot more than that.
So the answer to the question "What's the difference between xmalloc
and malloc
is: it depends. xmalloc
is a non-standard, project-specific function, so it could do anything at all. The only way to know for sure is to read the code.
I have seen xmalloc while working on IBM AIX. xmalloc is a kernel service provided by AIX.
Nothing can explain a function better than the function's man page in my opinion. So I am pasting the below details from the man page
Purpose: Allocates memory.
Syntax:
caddr_t xmalloc ( size, align, heap)
Parameters:
size: Specifies the number of bytes to allocate.
align: Specifies the alignment characteristics for the allocated memory.
heap : Specifies the address of the heap from which the memory is to be allocated.
Description:
The xmalloc kernel service allocates an area of memory out of the heap specified by the heap parameter. This area is the number of bytes in length specified by the size parameter and is aligned on the byte boundary specified by the align parameter. The align parameter is actually the log base 2 of the desired address boundary. For example, an align value of 4 requests that the allocated area be aligned on a 2^4 (16) byte boundary.
There are multiple heaps provided by the kernel for use by kernel extensions. Two primary kernel heaps are kernel_heap and pinned_heap. Kernel extensions should use the kernel_heap value when allocating memory that is not pinned, and should use the pinned_heap value when allocating memory that should always be pinned or pinned for long periods of time. When allocating from the pinned_heap heap, the xmalloc kernel service will pin the memory before a successful return. The pin and unpin kernel services should be used to pin and unpin memory from the kernel_heap heap when the memory should only be pinned for a limited amount of time. Memory from the kernel_heap heap must be unpinned before freeing it. Memory from the pinned_heap heap should not be unpinned.
If one is interested in knowing more about this function can visit the following link: IBM AIX Support
an primitive example of xmalloc.c in 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;
}
then in your code header (early) you put
#define malloc(m) xmalloc(m)
to silently rewrite the source before compilation. (you can see the rewritten code by invoking the C preprocessor directly and saving the output. )
if crashing your program is not what you want you can do something different
Users don't enjoy losing their data to a built-in crash command in their program.
xmalloc()
is a non-standard function that has the motto succeed or die. If it fails to allocate memory, it will terminate your program and print an error message to stderr
.
The allocation itself is no different; only the behaviour in the case that no memory could be allocated is different.
Use malloc()
, since it's more friendly and standard.