是否有额外的空闲开销检查空指针?

时间:2015-09-07 00:04:18

标签: c pointers null

在调用NULL之前,我不是在询问是否需要检查指针是否为free,我知道我没有。相反,我问的是free的(典型)实现是否会牺牲时间来在解除分配之前检查NULL指针,或者进程的性质是否实际上不会调用任何额外的开销。例如,知道free做什么的人可能会想到它的实现可能是这样的:

void free(void* ptr){
    if(ptr != NULL){
        <proceed with deallocation>
    }
}

但这与C哲学相矛盾,即不支付我不能使用的东西:如果我知道我不会将NULL指针传递给free,那么就不应该有性能缺陷结果是。因此,我很确定free 通常会调用这样的费用,在这种情况下我想知道如何/为什么。我试着寻找答案,但我看到一个问题的飓风,询问是否删除NULL指针是安全的。

编辑:我已经对答案和评论感到满意,但为了将来的参考,我想弄清楚我在问什么。我是从程序员的角度询问在我调用NULL之后程序的状态和我的free指针是什么。我对堆管理器的角度更感兴趣。举一个我的意思的例子,假设我在一家面包店,我的工作就是把桌子上的东西全部扔进垃圾桶里。它可能是5个布朗尼蛋糕,十几个饼干,或者其他任何东西,是的,我知道这不是最好的类比,而是忍受我。我想知道是否存在堆管理器,例如,如果有&#34;什么都没有&#34;在桌子上我是否倾销&#34;没有&#34;进入垃圾桶会产生任何不同,这将是隐含的处理&#34;什么都没有。&#34; 显式处理&#34;没有&#34;在我尝试转储它之前,我会检查表格以查看是否有任何内容。我想知道堆管理器是否通常可以隐式地处理这种情况,即通过做他们通常会做的事情,偶然也处理一个NULL指针,或明确地,通过明确检查是否一个指针是NULL。正如awksp的评论所揭示的那样,因为要求在NULL指针的情况下没有任何字面意义,所以必须确实存在显式检查,因为将NULL指针视为相同因为其他人不会是无操作,因此我们必须事先明确检查NULL

3 个答案:

答案 0 :(得分:2)

这就是为什么在free()中检查NULL不仅仅是一个好主意:

当您使用malloc()时,您不必记住您要求的内存量:堆管理器会为您执行此操作。因此,当您释放一个块时,它必须将释放的块(具有正确大小)添加到用于保存此信息的任何数据结构中。

那么,怎么知道它的大小呢?它可以在包含所有已分配内存列表的其他结构中找到指针,但如果没有某种Content-addressable-memory硬件,则可能会很慢。所以,大多数堆管理器使用一种技巧来存储关于你在指向它们时给你的指针之前分配的块的元数据。 (它不可能 在块结束时,因为记住我们不知道实际的块大小......)

如果堆管理器没有明确检查NULL,它将开始尝试访问负地址(例如,NULL-16)的内存,这可能会导致访问冲突和各种其他不良影响。最好在开始之前获得一个微不足道的(if x=NULL)

是否会导致性能下降?可能,但与典型堆管理器中所需的所有块合并,列表搜索等相比,它是完全无关紧要的。

答案 1 :(得分:1)

实际上free所做的只是将分配的内存块(如果有的话)返回给您的操作系统,无论是使用malloc还是realloc分配还是其他什么,应该是一个指向块开头的指针,块的长度保存在某个地方。它显然(在大多数平台上)每个字节分配8字节的开销,这是一个很大的开销(就内存使用而言),但它实际上是操作系统所做的。

所以当根据上述内容传递给ANSII C函数null pointer时,free谈论malloc将无效,因为它指的是没有内存块,所以只要它在引擎盖下什么都不做,它会产生时间开销。

freeoperating systems实施始终是开发$("#bkmrk").click(function() { if(localStorage) { localStorage.setItem("name",$("#repo_name").val()); } else { console.log("local storage is not supported!!"); } $("#ul_bkmrk").append("<li>"+localStorage.getItem("name")+"</li>"); }); 的最大问题之一。所以我建议你自己实施一次,然后尝试尽可能减少开销。

答案 2 :(得分:1)

首先 - 在空指针上调用free()并没有真正做任何事情。你不需要检查,在零的情况下你会被覆盖。

第二 - 在任何现代系统中,在使用它之前检查指针会产生很小的开销,甚至可能只有一个时钟周期,这实际上可以忽略不计,所以不要犹豫 - 检查何时需要。不是free()的情况,但有很多情况下您需要检查。

指针必须在使用前到达CPU寄存器,因此额外检查null将非常有效。与从ram或线程上下文切换中获取数据相比,它没有任何意义。