我正在学习C ++而且我开始知道指针如果未初始化可能会指向内存中的随机位置并产生内存可能被其他程序使用的问题。
现在,如果是这种情况,我们不应该在代码的任何部分使用此行:
int* ptr;
相反,我们应该有像
这样的东西int* ptr = NULL; //Is this going to avoid the problem
请建议,因为我在很多书中都看过第一行( int* ptr;
),所以我对此表示怀疑。如果可能的话也给出一些例子。
答案 0 :(得分:36)
int* ptr = NULL; //Is this going to avoid the problem
这会导致ptr
指向NULL
,您可以将其明确检查为默认值/未初始化值。它可以防止你描述的问题,但粗心的程序员仍然可以在不检查的情况下意外取消引用空指针,从而导致未定义的行为。
主要优点是方便您检查ptr
是否已初始化为任何内容,即:
if (ptr != NULL)
{
// assume it points to something
}
由于这非常惯用,因此不初始化指向NULL
的指针非常危险。指针将初始化为非NULL垃圾值,并不真正指向任何真实的垃圾值。最糟糕的是,上面的检查会通过,如果发生指针中的地址是您可以合法访问的内存,则会导致更严重的问题。在某些嵌入式环境中,您可能能够访问内存的任何部分,因此可能会意外损坏内存的随机部分或执行代码的随机部分。
答案 1 :(得分:9)
始终初始化变量。
有时,您可能希望初始化为NULL
,但大多数情况下,您应该能够将指针初始化为它应该保存的值。尽可能晚地声明变量,并在那时初始化它们,而不是代码中的15行。
答案 2 :(得分:6)
该行:
int* ptr;
绝对不能保证将指针值初始化为任何特定的值。 这一行:
int* ptr = NULL;
将指针初始化为指向零地址,这实际上将永远不会保留任何有用的东西,并且通常会将其作为无效指针值进行检查。
当然,正如Doug T.所说,仍然有可能尝试使用这个指针而不检查它,所以它会崩溃所有相同。
显式初始化为NULL的优点是确保在将指针设置为有用的东西之前取消引用指针会崩溃,这实际上是一件好事,因为它可以防止代码在屏蔽严重错误时“意外”工作。 p>
答案 3 :(得分:2)
如果由于任何原因你无法在声明发生时初始化它,那么将指针初始化为NULL总是更好。例如:
Object *ptr = new Object();
通常,函数可以针对NULL检查指针的值,以验证指针之前是否已初始化。如果你没有明确地将它设置为NULL,并且它指向一个随机值,那么它可能会被解除引用而导致段错误。
答案 4 :(得分:1)
如果未使用指针,编译器将忽略它。将它初始化为NULL是安全的事情,imho。
你确定你不会混淆功能声明吗?将函数声明为
是很常见的char * do_something(const char * one,const char * two);
在这种情况下,指针用于指定要传递的参数类型。
答案 5 :(得分:1)
C ++继续从C开始,它不是为了安全而设计的;它旨在提高效率。因此,因此不会初始化自动变量。在您初始化之前确保没有使用指针(尽管如果您不初始化变量,许多编译器会警告您),这取决于您。
答案 6 :(得分:1)
int a,*ptr;
现在
print(ptr,*ptr)
在上面的代码中,有两种情况可能:
如果ptr中的默认值不是某些已用程序存储器的地址,则执行它。
输出:
ptr *ptr
eg. 0x400730 -1992206795
如果ptr中的默认地址是某个已用程序存储器的地址,它将给出错误(分段错误)。例如。如果内存中变量a的地址也是0x400730。
答案 7 :(得分:-1)
在C ++中,你通常应该完全避免普通的旧指针。标准库类,智能指针(仅限于各种库中的C ++ 0x,如Boost或Loki)和引用可以而且应该在大多数地方使用。
如果你不能避免指针,确实最好用初始化来声明它们,在大多数情况下它们不应该是NULL,而是实际的目标值,因为在C ++中你可以自由地混合声明和表达式,所以你可以和应该只在你有意义值的那一点声明变量。
对于C来说情况并非如此,你必须经常使用指针,所有变量必须(或者必须在C99之前;我不完全确定)在范围的开头声明。很多人的C习惯仍然不适合C ++。