我已经看到了几种不同的方法来进行malloc错误检查。有一种方式比另一种更好吗?有些退出代码比其他代码更好吗?使用fprintf和stderr比使用printf语句更好吗?使用退货而不是退出更好?
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(1);
}
res = malloc(strlen(str1) + strlen(str2) + 1);
if (!res) {
fprintf(stderr, "malloc() failed: insufficient memory!\n");
return EXIT_FAILURE;
}
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(-1);
}
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(EXIT_FAILURE);
}
char *ptr = (char *)malloc(sizeof(char) * some_int);
if (ptr == NULL) {
fprintf(stderr, "failed to allocate memory.\n");
return -1;
}
char* allocCharBuffer(size_t numberOfChars)
{
char *ptr = (char *)malloc(sizeof(char) * numberOfChars);
if (ptr == NULL) {
fprintf(stderr, "failed to allocate memory.\n");
exit(-1);
}
return ptr;
}
答案 0 :(得分:5)
当您使用malloc()
,calloc()
和realloc()
检测到错误(即它们返回NULL指针)时,会设置errno
。然后,您可以使用标准函数perror()
来打印错误,而无需进行自己的格式化。请注意,它会自动打印到stderr
,无需为此烦恼。
此外,如果您的应用程序将错误视为致命错误,则必须结束该过程。如果您的代码位于main()
函数中,那么使用return EXIT_FAILURE;
就可以了,如果没有,请使用exit(EXIT_FAILURE);
。在这种情况下,不建议您使用自己的返回代码退出。
如果错误不被视为致命错误,那么由您决定如何处理错误。
另请注意,当realloc()
失败并返回NULL
时,旧指针仍然有效,因此必须free
d才能离开。
答案 1 :(得分:3)
这个包装器怎么样:
void *safe_malloc(size_t n)
{
void *p = malloc(n);
if (p == NULL) {
fprintf(stderr, "Fatal: failed to allocate %zu bytes.\n", n);
abort();
}
return p;
}
然后在任何地方使用safe_malloc
,并且不要担心错误检查。
许多程序都不是为了优雅地处理内存分配失败而编写的,而且这种解决方案适用于那些应用程序。如果您的应用程序 能够在内存分配失败后继续,那么您可能不会问这个问题。
答案 2 :(得分:2)
这不是关于如何检查错误,而是你对错误的处理方式。在所有情况下,您都可以看到使用的常用代码是
if (ptr == NULL) {....}
当您遇到返回值为NULL
时,您之后所做的就是您的个人选择。有些开发人员甚至喜欢assert()
该计划。
在此期间,gcc为你设置了errno。因此,您可以使用它来获取更多详细信息并使用它。
总之,您可以为您的计划做最适合您的事情。
答案 3 :(得分:1)
规则#1。请务必检查malloc
的返回值(以及realloc
)是否有错误。
规则#2。除非您能够优雅地恢复,否则请始终向stderr
打印错误消息,并提供相关信息。
规则#3。始终以非零状态退出,表示存在错误。 (确切的非零值并不重要。)
“包装器”功能是同时处理所有三个规则的绝佳方式,如果你的程序可以容忍急剧退出(也就是说,不保存可能存在的任何内存数据)重要)。
规则#2有一些例外,但它们仍然涉及以某种方式报告错误(不一定是立即fprintf
到stderr
),所以基本规则就是。
答案 4 :(得分:0)
perror("more details");
将(尝试)将错误(根据errno)打印到stderr
。
你可以使用它。
static void die(const char* msg){ perror(msg); exit(1); }
您还可以保存errno并将其转换为BSD样式的sysexits.h代码,或者以某种方式将其线性序列化到父进程(通过exit
使用errno或其线性转换)。