我正在学习C++,我了解到如果指针未初始化,则可能会指向内存中的随机位置,并创建一些问题,这些内存可能被其他程序使用。
现在如果是这种情况,我们就不应该在代码的任何部分中出现以下行:
int* ptr;
相反,我们应该有类似于
int* ptr = NULL; //Is this going to avoid the problem
请给出建议,因为我在很多书中都看到了第一行(int* ptr;
),所以我有这个疑问。如果可能的话,请举些例子。
我正在学习C++,我了解到如果指针未初始化,则可能会指向内存中的随机位置,并创建一些问题,这些内存可能被其他程序使用。
现在如果是这种情况,我们就不应该在代码的任何部分中出现以下行:
int* ptr;
相反,我们应该有类似于
int* ptr = NULL; //Is this going to avoid the problem
请给出建议,因为我在很多书中都看到了第一行(int* ptr;
),所以我有这个疑问。如果可能的话,请举些例子。
int* ptr = NULL; //Is this going to avoid the problem
这将导致ptr
指向NULL
,你可以明确地检查它作为默认/未初始化值。它可以防止您所描述的问题,但是一个不小心的程序员仍然可能在没有检查的情况下意外解除对空指针的引用,从而导致未定义的行为。主要优点是方便您检查ptr
是否已经被初始化成任何东西,即: if (ptr != NULL)
{
// assume it points to something
}
由于这种用法相当常见,不将指针初始化为NULL
会非常危险。指针将被初始化为非NULL
的垃圾值,实际上并没有指向任何真正的内容。最糟糕的是,上面的检查将通过,如果恰好该指针中的地址是您可以合法访问的内存,则会导致更严重的问题。在某些嵌入式环境中,您可能能够访问内存的任何部分,因此您可能会意外地损坏随机部分的内存或执行代码的随机部分。
始终初始化你的变量。
偶尔,你可能想要将其初始化为NULL
,但大多数情况下,你应该能够将指针初始化为它应该持有的值。尽可能晚地声明变量,并在那个点进行初始化,而不是在代码中后面15行进行初始化。
这行代码:
int* ptr;
并不保证将指针的值初始化为特定值。
以下是代码:
int* ptr = NULL;
将指针初始化为指向地址零,实际上从来不会有任何有用的内容存在,而且通常会检查它是否为无效指针值。
当然,正如Doug T.所说,仍然有可能尝试在未经检查的情况下使用该指针,因此它会崩溃。
明确地初始化为NULL的优点是确保在将其设置为有用的内容之前对指针进行解引用将导致崩溃,这实际上是一件好事,因为它可以防止代码在掩盖严重缺陷的同时“意外”运行。
如果由于某种原因无法在声明时初始化指针,最好将其初始化为NULL。例如:
Object *ptr = new Object();
通常,函数可以检查指针的值是否为NULL,以验证指针在初始化之前已被初始化。如果您没有将其明确设置为NULL,并且它指向随机值,则可能会导致引用无效而导致段错误。
C++继承了C的特性,它并非被设计成安全的语言,而是为了追求效率。因此,自动变量不会被初始化。你需要确保在使用指针之前将其初始化(虽然许多编译器如果你没有初始化变量会发出警告)。
如果指针没有被使用,编译器将会忽略它。在我的看法中,将其初始化为NULL是安全的做法。
你确定你没有混淆函数声明吗?一个函数被声明为
char* do_something(const char* one,const char* two);
在这种情况下,指针用于指定要传递的参数类型。
int a,*ptr;
print(ptr,*ptr)
It'll execute if default value in ptr is not the address of some used memory of program.
Output:
ptr *ptr
eg. 0x400730 -1992206795
It'll give error (segmental fault) if default address in the ptr is the address of some used memory of program. E.g. if the address of variable a in the memory is also 0x400730.
在C++中,你应该尽量避免使用普通指针。标准库类、智能指针(直到C++0x只存在于各种库中,如Boost或Loki)和引用可以并且应该在大多数情况下代替它们。
如果你无法避免使用指针,最好声明它们时进行初始化,在大多数情况下不应该是NULL,而是实际的目标值,因为在C++中,你可以自由地混合声明和表达式,所以你只能在有意义的值的点上声明变量。
这在C语言中并非如此,你必须经常使用指针,并且所有变量都必须(或者在C99之前必须)在作用域的开头声明。因此,许多人仍然有从C语言继承下来的不适用于C++的坏习惯。