当我创建一个指向某个结构,我必须将它设置为NULL,则ALLOC它然后使用它? 为什么?
Answer 1:
没有,没有要求(只要语言而言)宣布,当它的指针变量初始化为任何事情。 从而
T* ptr;
是引入了一个名为变量的有效申报ptr
用一个不确定的值。 你甚至可以使用在某些方面的变量没有先分配任何东西,或将其设置为任何特定的值:
func(&ptr);
Answer 2:
不,你不必将它设置为NULL
,但有些人认为是个好习惯,因为它提供了一种新的指针的值,使得它明确这不是在任何东西(还)指向。
如果要创建一个指针,然后立即另一个值分配给它,那么就真的没有将它设置为多少价值NULL
。
这是设置一个指向一个好主意, NULL
你释放它指向的内存后,虽然。
Answer 3:
根据C标准,不进行初始化自动存储变量离开其值不确定的。
你肯定鼓励指针设置为NULL每当替代是具有不确定的值指针。 有一个不确定的值指针的用法是不确定的行为 ,如果你已经习惯了C语言编程和来自更高级别的语言,你可能无法正确把握的概念。
未定义行为意味着什么事情都可能发生 ,这是因为C的理念是让程序员C标准的一部分有负担控制的事情,而不是保护他从自己的错误。
你要避免在代码中未定义行为:这是很难调试的东西时,任何行为可以occurr。 它不是由编译器捕获,并且您的测试可能总是传递,留下被忽视的bug,直到它是非常昂贵的纠正。
如果你做这样的事情:
char *p;
if(!p) puts("Pointer is NULL");
其实你不知道这是否if
控制将是真的还是假的。 这是在大型的程序,你可以声明你的变量,然后很远,在时间和空间的地方使用它极其危险的。
当您引用释放的内存同一个概念。
free(p);
printf("%s\n", p);
p = q;
其实你不知道你会得到与上面的两个语句什么。 不能正确测试它,你不能确定你的结果。 您的代码可能看起来工作,因为释放的内存被回收,即使它可能已经被改变......你甚至可以覆盖内存,或共享相同的内存损坏其他变量。 所以,你仍然有一个迟早会体现出来,可能是很困难的调试它的错误。
如果设置指针为NULL,你保护自己免受这些危险的情况:在您的测试,你的程序将有一个确定的,可预测的行为,将快速失败和便宜。 你得到一个段错误,你抓的bug,你修复bug。 清洁和简单的:
#include <stdio.h>
#include <stdlib.h>
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;
}
所以,当你初始化一个指针,特别是在大型程序时,您希望他们能够明确地initliazed或设置为NULL。 你不希望他们得到一个不确定的值,从来没有。 我应该说,除非你知道自己在做什么 ,但我希望永远代替。
Answer 4:
不,不要忘了初始化必须是一个空指针的。 在现代C A非常方便的成语是他们第一次使用声明变量
T * ptr = malloc(sizeof *ptr);
这避免了你很多回忆的类型,以及是否一个变量已经被初始化的拼劲。 只有当你不知道在哪里(或者即使)它以后初始化,那么你应该明确它初始化为一个空指针。
因此,作为一个经验法则,总是初始化变量为适当的值。 “适当0
的类型”始终是一个不错的选择,如果你没有在手边一个更好的。 对于所有类型的,C是由类似的,例如,它的作品。
未初始化的变量是在大多数情况下,过早的优化。 只有通过你的变量,当你看到有一个真正的性能瓶颈,在那里。 尤其是,如果有同样的功能内的分配的使用初始值之前,安迪现代编译器将优化你的初始化了。 首先想到你的程序的正确性。
Answer 5:
你没有,除非你不希望它吊着一段时间。 你知道你应该释放(防御型)之后。
Answer 6:
你不必初始化为NULL。 如果您打算立即分配它,你可以跳过它。
在可以处理错误就像下面这个例子时有用。 在这种情况下,以突破结束后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