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 onmalloc
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
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);
}