xmalloc和malloc之间有什么区别?

xmalloc和malloc之间有什么区别?,c,C,内存分配的xmalloc()和malloc()之间有什么区别? 使用xmalloc()有什么好处吗?xmalloc()是一个非标准函数,其座右铭是成功或死亡。如果无法分配内存,它将终止您的程序并将错误消息打印到stderr 分配本身也不例外;只有在无法分配内存的情况下的行为是不同的 使用malloc(),因为它更友好、更标准。xmalloc不是标准库的一部分。对于懒惰的程序员来说,这通常是一个非常有害的函数,这在许多GNU软件中很常见,如果malloc失败,就会调用abort。根据程序/库的不同

内存分配的
xmalloc()
malloc()
之间有什么区别?
使用
xmalloc()
有什么好处吗?

xmalloc()
是一个非标准函数,其座右铭是成功或死亡。如果无法分配内存,它将终止您的程序并将错误消息打印到
stderr

分配本身也不例外;只有在无法分配内存的情况下的行为是不同的


使用
malloc()
,因为它更友好、更标准。

xmalloc
不是标准库的一部分。对于懒惰的程序员来说,这通常是一个非常有害的函数,这在许多GNU软件中很常见,如果
malloc
失败,就会调用
abort
。根据程序/库的不同,它还可以将
malloc(0)
转换为
malloc(1)
,以确保
xmalloc(0)
返回唯一的指针

在任何情况下,
abort
ing on
malloc
failure都是非常糟糕的行为,尤其是对于库代码。最臭名昭著的例子之一是GMP(GNU多精度算术库),它在计算内存不足时中止调用程序


正确的库级代码应该总是通过备份在中间的部分完成的操作并将错误代码返回给调用方来处理分配失败。然后调用程序可以决定要做什么,这可能涉及到保存关键数据。

K&R c中xmalloc.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;
}
#包括
外部字符*malloc();
空虚*
xmalloc(尺寸)
无符号大小;
{
void*new_mem=(void*)malloc(大小);
if(new_mem==NULL)
{
fprintf(stderr,“致命:内存耗尽(xmalloc为%u字节)。\n”,大小);
出口(-1);
}
返回新的_mem;
}
然后在代码头(早期)中

#定义malloc(m)xmalloc(m)

在编译之前以静默方式重写源代码。 (您可以通过调用 直接使用C预处理器并保存输出。)

如果程序崩溃不是你想要的,你可以做一些不同的事情

  • 使用垃圾收集器
  • 重新设计你的代码,减少内存占用
  • 让程序中的错误检查代码优雅地处理内存不足或其他分配错误

用户不喜欢将数据丢失给程序中内置的崩溃命令

正如其他人所提到的,
xmalloc
确实经常被实现为一个包装函数,它调用提供的操作系统
malloc
,并在失败时盲目调用
abort
exit
。但是,许多项目都包含一个
xmalloc
函数,该函数在退出之前尝试保存应用程序状态(例如,请参见)

就个人而言,我认为
xmalloc
是一种特定于项目的扩展
malloc
,而不是退出
malloc
。虽然我不记得曾经看到过一个版本没有调用
abort
exit
,但其中一些版本所做的远远不止这些


因此,“xmalloc和malloc之间有什么区别”这个问题的答案是:这要看情况而定。
xmalloc
是一个非标准的、特定于项目的函数,所以它可以做任何事情。唯一确定的方法是阅读代码。

xmalloc
是libiberty的一部分。

这是一个GNUtils库

malloc
是ANSI C

xmalloc
通常包含在许多重要GNU项目的源代码中,包括GCC和Binutils,这两个项目都大量使用它。但是也可以将它构建为一个动态库,用于您的程序中。例如,Ubuntu有
libiberty dev

xmalloc
记录在:上,并在GCC 5.2.0上实现

正如其他人所提到的,这非常简单:

  • 尝试
    malloc
  • 如果失败了
    • 打印错误消息
    • 呼叫
      exit

我在IBM AIX上工作时见过xmalloc。 xmalloc是AIX提供的一种内核服务

在我看来,没有什么比函数的手册页更能解释函数了。因此,我从手册页粘贴了以下详细信息

用途:分配内存

语法:

caddr\u t xmalloc(大小、对齐、堆)

参数:

大小:指定要分配的字节数

对齐:指定分配内存的对齐特征

heap:指定要从中分配内存的堆的地址

说明:

xmalloc内核服务在heap参数指定的堆外分配一个内存区域。该区域是size参数指定的长度字节数,并在align参数指定的字节边界上对齐。align参数实际上是所需地址边界的日志基数2。例如,align值为4要求分配的区域在2^4(16)字节边界上对齐

内核提供了多个堆供内核扩展使用。两个主要内核堆是内核堆和固定堆。内核扩展在分配未固定的内存时应使用内核堆值,在分配应始终固定或长时间固定的内存时应使用固定堆值时间。当从固定的_堆进行分配时,xmalloc内核服务将在成功返回之前固定内存。当内存只应固定有限的时间时,应使用固定和取消固定内核服务从内核_堆固定和取消固定内存
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);
}