测试ENOMEM的errno,而不是将一系列malloc调用与NULL进行比较

测试ENOMEM的errno,而不是将一系列malloc调用与NULL进行比较,c,C,通常,测试malloc的结果是否为NULL,以了解内存分配是否成功。通过一系列malloc调用,这将成为一组冗长或乏味的比较 相反,是否可以在malloc调用系列的顶部设置errno=0,然后在末尾测试errno==ENOMEM 这假设如果任何分配失败,程序或功能无法继续,必须返回/退出。它还假设malloc调用是连续的,并且根据手册,malloc只能将errno设置为ENOMEM 一个示例类似于以下代码: #include <stdlib.h> #include <errno

通常,测试
malloc
的结果是否为
NULL
,以了解内存分配是否成功。通过一系列
malloc
调用,这将成为一组冗长或乏味的比较

相反,是否可以在
malloc
调用系列的顶部设置
errno=0
,然后在末尾测试
errno==ENOMEM
这假设如果任何分配失败,程序或功能无法继续,必须返回/退出。它还假设
malloc
调用是连续的,并且根据手册,
malloc
只能将
errno
设置为
ENOMEM

一个示例类似于以下代码:

#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

#define N (1 << 20)

int main()
{
        double *a = NULL;
        double *b = NULL;
        double *c = NULL;

        errno = 0;
        a = malloc(N * sizeof *a);
        b = malloc(N * sizeof *b);
        c = malloc(N * sizeof *c);
        if (errno == ENOMEM) {
                perror(NULL);
                free(a);
                free(b);
                free(c);
                return EXIT_FAILURE;
        }
        errno = 0;

        /* Do interesting stuff */

        free(a);
        free(b);
        free(c);
        return EXIT_SUCCESS;
}
#包括
#包括
#包括
#定义N(1)
相反,可以在malloc调用系列的顶部设置errno=0,然后在末尾测试errno==enome吗

是的,只要将
malloc
的实现记录为将
errno
设置为
ENOMEM
,您就可以。C11标准(§7.22.3.4)中的规范只提到返回的指针将为
NULL
,而不是将设置
errno
,因此您的代码在技术上是不可移植的

macOS、Windows和Linux中默认的
malloc
实现设置了
errno
,因此这是世界上大多数计算机的覆盖范围。但是,如果需要真正的可移植性,最后只需编写

if (a == NULL || b == NULL || c == NULL)
{
    // Handle the failure
}

附录:在
malloc
s之后,无需将
errno
重置回零。

不,您不能以便携方式安全地执行此操作

根据C标准:

程序启动时,初始线程中的
errno
值为零(其他线程中的errno初始值为不确定值),但决不能由任何库函数设置为零。如果本国际标准中的函数说明中未记录使用
errno
,则库函数调用可将
errno
的值设置为非零


因为
malloc()
没有被C标准记录为设置
errno
,成功后可以自由咀嚼
errno

我对答案的最佳猜测是,这确实是安全的,或者malloc将errno设置为ENOMEM在malloc实现中不如malloc返回NULL那么标准。如果malloc成功,但在b和C中失败,不会免费(b)和免费(c)给出错误吗?我知道它不会给C++带来错误,但是我不确定C编译器。如果你的代码> Malc ErnOn/Cuth>错误(可能不是这样,它是依赖于平台的),则您的代码是安全的。@suvenpandey如果
malloc
失败,它也将返回
NULL
。使用
NULL
参数调用
free
在C中是安全的。@user3629249我可以自己回答最后一个问题,我意识到:检查
fp==NULL
,然后检查
errno
的值以查看实际错误是什么r是。为了完整起见,标准中是否有相关章节的链接,或者这是不可能的?@9769953@9769953我已经添加了章节号。互联网上没有现成的HTML版本的标准,除非交上一大笔现金。我有一份我得到的最新草稿的PDF,并且出于所有意图和目的都是id诱人。@AlexeyFrunze和JeremyP:谢谢添加/链接!