给出以下代码:
f1()
{
int *x;
f2(&x);
}
f2(int **x)
{
// Before any processing, make sure that the reference to x is NULL
if (x != NULL)
{
*x = NULL;
}
}
我不确定这段代码是否真的有意义。我想做的是确保指向x的指针(在f1中声明并由f2接收为参数)为NULL(因为在f1中声明未初始化为NULL)。
答案 0 :(得分:1)
f1() { int *x; f2(&x); }
f2 (int **x) {
// Before any processing, make sure that the reference to x is NULL
if (x != NULL) *x = NULL;
}
在f1()中显然有一个错误(未初始化的变量),您想在f2()中进行测试。实际上,如果将变量x用作f2()的out
参数,则f1()可能很好,但是从此示例来看,您的解释似乎并非如此。
f2()可以检查x是否为NULL,但不能检查其他错误,例如errating指针。在这里,通常在C语言程序中,通常
f2()无法以任何方式检查其参数的有效性。使用其他机制,可能有多达99%的可能:例如,如果指针不为NULL,则对其取消引用并检查特殊标记,或将其传递给可以进行检查的其他函数。无论如何这都是棘手的,因为通配指针无论如何都会触发异常。而且,即使取消引用指针不会触发异常,并且由于巧合,应该在正确的位置放置正确的标记,但这不能保证指针的正确性!
但是,正如上面的评论所指出的,问题更广泛。如果被调用函数发现参数无效,该怎么办?只是为了避免出现分段错误而忽略它是一个起点,但是不够安全,因为函数的调用者可能希望被调用的函数做一些有用的事情。如果没有完成有用的操作,则必须通知调用方,否则将以错误的假设进行操作。在某些情况下,可以接受这种缺乏检查的方式,但是无论如何它们都不是很优雅。
我已经读到某个地方,对于某个函数来说,检查输入参数的有效性并不总是正确的:用这种方式编写的软件往往更长,更慢,甚至可能存在缺陷,因为所添加代码的每一行都可能引入错误。编写良好的函数应假定调用者行为良好。可能在某些危险情况下,还是建议进行检查。
答案 1 :(得分:0)
说实话,对此段代码有很多评论,但我想您是用原始代码的细节来阐明您的观点的,所以我不会深入探讨这些细节...
输入您的代码
f1()
{
int *x;
f2(&x); /* you are passing address of the variable x which is a pointer to an int */
}
f2(int **x)
{
// Before any processing, make sure that the reference to x is NULL
if (x != NULL)
{
*x = NULL;
}
/* at this point, the memory location pointed by the passed argument x,
* which happen to be another pointer to an int, is NULL. The local
* variable x of f2() is not NULL, only the memory location it is point
* to contains the NULL value.
*/
}