如果您不希望(或不能)使用地址初始化指针,我经常听到人们说您应该使用NULL它来初始化指针,这是一个好习惯。
您可以找到人们也在SO中说类似的话,例如在这里。
在许多C项目的工作,我不认为这是一个很好的做法,或者至少在某种程度上优于未初始化与任何指针。
我最大的理由之一是:初始化一个指针会NULL增加空指针取消引用的机会,这可能会使整个软件崩溃,这很糟糕。
因此,您能告诉我说这是一个好习惯还是人们只是说这是理所当然的原因(就像您应该始终初始化一个变量一样)吗?
请注意,我尝试在Misra 2004中查找,也没有找到任何规则或建议。
更新:
因此,大多数注释和答案都给出了使用该指针之前可能具有随机地址的主要原因,因此最好将其设置为null,以便您更快地解决问题。
为了使我的观点更加清楚,我认为从实用的角度来看,如今在商业C软件中这没有任何意义。大多数静态分析器都会正确检测到所使用的未分配指针,这就是为什么我更喜欢将其取消初始化,因为如果我使用NULL对其进行初始化,那么当开发人员忘记将其分配给“真实”地址时,它会通过静态分析器,并会导致运行时出现空指针问题。
你说
我最大的理由之一是:使用NULL初始化指针会增加空指针取消引用的机会,这可能会使整个软件崩溃,这很糟糕。
我认为主要的原因实际上正是由于此。如果您不初始化指向NULL的指针,那么如果存在解引用错误,则将很难发现问题,因为指针将不会被设置为NULL,这将是最有可能的垃圾值,看起来就像一个有效的指针。
C几乎没有运行时错误检查,但是要陷阱的一件小事是尝试写入空指针表示的地址,大多数实现都会这样做。而且,由于保证NULL不会引用有效地址,因此运行时环境(通常是操作系统)能够捕获任何取消引用NULL的尝试,而与读/写无关。陷阱将识别取消引用发生的位置,而不是程序最终可能失败的位置,从而使错误的识别更加容易。
如果取消引用未初始化的指针,则结果是不确定的-可能会崩溃,可能不会崩溃,但仍然会出错。
如果它确实崩溃了,您将无法确定如何或什至何时发生故障,因为它可能会导致数据损坏,或读取无效数据,这些数据在以后使用该损坏的数据之前可能不会起作用。故障点不一定是错误点。
因此,这样做的目的是使您获得确定性的失败,而如果不进行初始化,则可能会发生任何事情-包括什么都没有发生,从而给您留下了未被发现的潜在错误。
我最大的理由之一是:使用NULL初始化指针会增加空指针取消引用的机会,这可能会使整个软件崩溃,这很糟糕。
确定性故障不是“可怕的”-它增加了您在开发过程中发现错误的机会,而不是让用户在部署后发现错误。您实际上在暗示的是,最好将这些错误留在里面并隐藏起来。保证对null的取消引用会被捕获,而取消取消对统一指针的引用则不会。
那说用null初始化,只有在声明时不能直接分配其他有效值的情况下,才应执行。也就是说,例如:
char* x = malloc( y ) ;
Run Code Online (Sandbox Code Playgroud)
比:
char* x = NULL ;
...
x = malloc( y ) ;
Run Code Online (Sandbox Code Playgroud)
相对于:
char* x ;
...
x = malloc( y ) ;
Run Code Online (Sandbox Code Playgroud)
请注意,我尝试在Misra 2004中查找,也没有找到任何规则或建议。
MISRA C:2004,9.1-在使用所有自动变量之前,应为其分配一个值。
也就是说,没有初始化为NULL的准则,只是要求初始化。如我所说,初始化为NULL优于初始化为有效指针。不要盲目遵循“必须初始化为NULL的建议”,因为规则只是“必须初始化”,有时合适的初始化值为NULL。