xmalloc和malloc有什么区别?
内存分配的xmalloc()
和malloc()
什么区别?
有没有使用xmalloc()
亲?
xmalloc()
是一个非标准的function,它的座右铭成功或死亡 。 如果分配内存失败,它将终止你的程序并向stderr
错误信息。
分配本身也不例外。 只有在没有内存可以分配的情况下的行为是不同的。
使用malloc()
,因为它更友好,更标准。
xmalloc
不是标准库的一部分。 对于懒惰的程序员来说,这通常是很多GNU软件中常见的一个非常有害的函数的名称,如果malloc
失败,它会调用abort
。 根据程序/库,它也可能将malloc(0)
转换为malloc(1)
以确保xmalloc(0)
返回一个唯一的指针。
无论如何, abort
malloc
失败是非常糟糕的行为,特别是对于库代码。 最臭名昭着的例子之一就是GMP(GNU多精度algorithm库),它在内存不足时进行调用程序的中断。
正确的库级代码应该始终处理分配失败,方法是撤销中间的任何部分完成的操作,并将错误代码返回给调用者。 调用程序然后可以决定要做什么,这可能涉及保存关键数据。
正如其他人所说, xmalloc
确实经常被实现为一个包装函数,它调用操作系统提供的malloc
并在失败时盲目地调用abort
或exit
。 但是, 许多项目包含一个xmalloc
函数,用于在退出之前尝试保存应用程序状态(请参阅neovim )。
就我个人而言,我认为xmalloc
是一种特定于项目的扩展 malloc
而不是一个正在退出的 malloc
。 虽然我不记得曾经看到一个没有结束或者exit
的版本, 但是有些版本比这个版本做得更多。
所以对“ xmalloc
和malloc
有什么区别是什么”这个问题的答案是这样的: xmalloc
是一个非标准的,特定于项目的函数,所以它可以做任何事情。唯一可以肯定的方法是阅读码。
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; }
然后在你的代docker(早)你把
#define malloc(m) xmalloc(m)
在编译之前默默地重写源代码。 (你可以通过直接调用C预处理器并保存输出来看到重写的代码。)
如果崩溃你的程序不是你想要的,你可以做一些不同的事情
- 使用垃圾收集器
- 重新devise你的代码less一点记忆猪
- 在您的程序中有错误检查代码来优雅地处理内存不足或其他分配错误。
用户不喜欢在他们的程序中丢失数据到内置的崩溃命令。
在IBM AIX上工作时,我看到了xmalloc。 xmalloc是AIX提供的内核服务。
在我看来,没有任何东西可以比函数的手册页更好地解释函数。 所以我正在粘贴man page中的下面的细节
目的:分配内存。
句法:
caddr_t xmalloc(大小,alignment,堆)
参数:
size:指定要分配的字节数。
align:指定分配内存的alignment特征。
堆:指定要从中分配内存的堆的地址。
描述:
xmalloc内核服务从heap参数指定的堆中分配一个内存区域。 此区域是由size参数指定的长度的字节数,并且在由align参数指定的字节边界上alignment。 align参数实际上是所需地址边界的日志基数2。 例如,alignment值为4请求分配的区域在2 ^ 4(16)字节边界上alignment。
内核提供了多个堆供内核扩展使用。 两个主要的内核堆是kernel_heap和pinned_heap。 内核扩展在分配非固定内存时应使用kernel_heap值,并且在分配内存时应使用pinned_heap值,该内存应始终固定或固定很长一段时间。 当从pinned_heap堆分配时,xmalloc内核服务将在成功返回之前locking内存。 当内存只能被固定一段时间时,引脚和解除内核服务应该用来从kernel_heap堆中引脚和解除内存。 释放kernel_heap堆中的内存之前,必须解除locking。 来自pinned_heap堆的内存不应该被取消固定。
如果有兴趣了解有关此function的更多信息,请访问以下链接: IBM AIX支持
xmalloc
是libiberty的一部分 https://gcc.gnu.org/onlinedocs/libiberty/index.html这是一个GNU 实用程序库。
malloc
是ANSI C.
xmalloc
通常包含在许多重要的GNU项目中,包括GCC和Binutils,两者都使用它。 但是也可以将其构build为dynamic库,以便在程序中使用。 例如Ubuntu有libiberty-dev
包。
xmalloc
logging在: 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