初始化时是否需要调用pointer = NULL?

当我创建一个指向某个结构的指针时,我是否必须将其设置为NULL,然后分配它然后使用它? 为什么?

不,在声明它时,没有要求(就语言而言)将指针变量初始化为任何东西。 从而

T* ptr; 

是一个有效的声明,它引入了一个名为ptr的变量,该变量具有不确定的值。 您甚至可以以某种方式使用变量,而无需先分配任何内容或将其设置为任何特定值:

 func(&ptr); 

不,你不必将它设置为NULL ,但有些人认为这是一个很好的做法,因为它为新指针提供了一个值,使其明确表示它没有指向任何东西(尚未)。

如果您正在创建一个指针,然后立即为其指定另一个值,那么将其设置为NULL确实没什么价值。

但是,在释放指向它的内存后,最好将指针设置为NULL

不,不要忘记初始化必须是空指针。 现代C中一个非常方便的习惯是在第一次使用时声明变量

 T * ptr = malloc(sizeof *ptr); 

这可以避免您在记住类型以及变量是否已经初始化时遇到很多麻烦。 只有当你不知道它在哪里(或者甚至是)稍后被初始化时,你肯定应该将它初始化为空指针。

因此,根据经验,始终将变量初始化为适当的值。 如果您手头没有更好的,那么“适合该类型的0 ”总是一个不错的选择。 对于所有类型,C都是这样制作的,因此它可以工作。

在大多数情况下,不初始化变量是过早优化。 当您发现存在真正的性能瓶颈时,只需检查您的变量。 特别是如果在使用初始值之前在同一函数内部有赋值,那么现代编译器将优化初始化输出。 首先考虑你的程序的正确性。

根据C标准,不初始化自动存储变量会使其值不确定。

当您的指针具有不确定的值时,我们绝对鼓励您将指针设置为NULL。 使用具有不确定值的指针是未定义的行为 ,如果您习惯于C编程并且来自更高级别的语言,则可能无法正确掌握这一概念。

未定义的行为意味着任何事情都可能发生 ,这是C标准的一部分,因为C的哲学是让程序员有责任控制事物,而不是保护他免受错误的影响。

您希望避免代码中未定义的行为:当任何行为发生时,调试内容非常困难。 它不会被编译器捕获,并且您的测试可能总是通过,直到修改它非常昂贵才会忽略该错误。

如果您这样做:

 char *p; if(!p) puts("Pointer is NULL"); 

你实际上并不知道控件是真还是假。 这在大型程序中非常危险,您可以在这些程序中声明变量,然后在空间和时间的某个地方使用它。

引用释放的内存时的相同概念。

 free(p); printf("%s\n", p); p = q; 

你实际上并不知道最后两个陈述会得到什么。 你无法正确测试它,你无法确定你的结果。 您的代码似乎可以工作,因为释放的内存可以被回收,即使它可能已被更改…您甚至可以覆盖内存,或者破坏共享相同内存的其他变量。 所以你仍然有一个迟早会出现的错误,并且可能很难调试它。

如果将指针设置为NULL,则可以保护自己免受这些危险情况的影响:在测试期间,程序将具有确定的,可预测的行为,这种行为将快速且廉价地失败。 你得到一个段错误,你抓住了错误,你修复了错误。 干净简单:

 #include  #include  int main(){ char* q; if(!q) puts("This may or may not happen, who knows"); q = malloc(10); free(q); printf("%s\n", q); // this is probably don't going to crash, but you still have a bug char* p = NULL; if(!p) puts("This is always going to happen"); p = malloc(10); free(p); p = NULL; printf("%s\n", p); // this is always going to crash return 0; } 

因此,当您初始化指针时,尤其是在大型程序中,您希望它们明确地初始化或设置为NULL。 你永远不希望他们获得不确定的价值。 我应该说, 除非你知道你在做什么 ,但我宁愿永远不要。

除非你不想让它悬挂一段时间,否则你不必这样做。 你知道你应该在解放后(防守风格)。

您不必初始化为NULL。 如果您打算立即分配,可以跳过它。

At可用于error handling,如下例所示。 在这种情况下,在p分配之后打破到最后会使q未初始化。

 int func(void) { char *p; char *q; p = malloc(100); if (!p) goto end; q = malloc(100); if (!q) goto end; /* Do something */ end: free(p); free(q); return 0; } 

此外,这是我的个人品味,总是使用calloc分配结构。 可以使用malloc未初始化字符串