30

通常的做法是在 malloc() 之后检查 NULL(内存是否已成功分配),例如

void *ptr = malloc(10);    
if (ptr != NULL) {  
  // do some thing usefull  
} else {  
 // no memory. safely return/throw ...  
}  

在内核中启用内存过量使用后,是否有机会获得 NULL?我应该遵循虔诚地检查每个分配的 NULL 的做法吗?尽管存在积极的过度使用机制(我猜值为 1),malloc 会返回 NULL 吗?

事实上,Android内核使用内存过度使用(不确定该值,很想知道它(过度使用值)及其意义)。Android(可能是第 3 方)中的一些框架源代码(C/C++)代码在分配后不会检查 NULL 也不会捕获 bad_alloc。我错过了什么吗?

SO中有一些关于过度使用内存的线程,但没有一个能解决我的困惑。

编辑:如果正在使用积极的过度使用,则不会返回 NULL(假设 1)。当没有可用的物理内存并且尝试访问分配的内存(写入分配的内存)时,OOM 将终止一些进程并为应用程序分配内存,直到它被依次终止(假设 2)。在任何一种情况下,我都认为不需要检查 NULL(内存被分配或进程被杀死)。我的假设是否正确?
便携性不是这个问题的关注点。

4

5 回答 5

38

是的,您仍然应该检查malloc. 在过度使用内存的环境中,您将无法检测到故障并从故障中恢复,因为当您写入已通过先前调用分配给程序的部分地址空间时,环境耗尽了所需的物理存储空间malloc

然而,这并不是导致malloc传统环境中失败的唯一问题。当程序的地址空间变得碎片化时,即使有足够的总物理内存来满足请求,对特别大的内存块的请求也可能会失败。因为没有连续的空闲地址空间范围malloc必然失败。无论环境是否过度使用内存,都必须通过malloc返回来表示这种类型的失败。NULL

于 2010-02-17T11:56:53.927 回答
7

您必须每次检查 NULL 的返回值。任何库函数都可能失败。甚至 fclose() 也会这样做(在断开连接的 NFS 共享上,并且来自 NFS 文件的 fclose 的错误意味着该数据未保存)。

大多数软件都写得不好,并且不包含所有检查。

malloc 不能返回 NULL 或指针以外的内容。全有或全无。如果您要求 10,则无法从 malloc 获得 1 个字节。

于 2010-02-15T15:01:08.803 回答
3

建议在所有可能返回 NULL 的函数调用中认真检查 NULL,无论内核是否具有过度提交的内存。

下面的以下代码段显示了如何检查调用是否malloc有效...

无效 *ptr = malloc(10);
如果(指针!= NULL){
   /* 在这里用 ptr 做一些事情 */
}别的{
   /* 如果失败在这里做一些事情 */
}

文件操作、内存操作仅举几例,失败时会返回 NULL。

希望这会有所帮助,最好的问候,汤姆。

于 2010-02-16T20:34:36.180 回答
1

好吧......在Linux上,因为内存不是页面支持(最初)并且只在第一次读/写后创建页面支持,操作系统总是会成功地给你内存(除非你用尽了地址空间,这在64位系统中是不可能的)。因此,如果它耗尽内存并且无法为您提供承诺的内存,OOM 杀手只会杀死您的应用程序或其他一些应用程序,以便为您提供所需的页面支持。所以无论你是否做NULL检查,结果都是一样的,崩溃......

于 2018-04-24T04:37:22.967 回答
-5

不,不需要检查malloc的结果。

早在 malloc 失败之前,操作系统就已经遇到了很多问题。

“OOM-Killer and overcommit”将是一个更好的选择。

什么?你的操作系统不支持“OOM-Killer and overcommit”?

这就是为什么你应该切换到 Linux(或 Android)!

于 2012-07-17T14:52:48.670 回答