38

我正在学习 C++,我开始知道如果未初始化的指针可能指向内存中的随机位置,并产生内存可能被其他程序使用的问题。

现在,如果是这种情况,我们不应该在代码的任何部分中包含这一行:

int* ptr;

相反,我们应该有类似的东西

int* ptr = NULL; //Is this going to avoid the problem

请提出建议,因为我在很多书中都看到了第一行(int* ptr;),所以我有这个疑问。如果可能的话,也举一些例子。

4

8 回答 8

45
int* ptr = NULL; //Is this going to avoid the problem

这将导致ptr指向NULL您可以显式检查的默认/未初始化值。它可以防止您描述的问题,但是粗心的程序员仍然可以在不检查的情况下意外取消引用空指针,从而导致未定义的行为。

主要优点是您可以方便地检查 是否ptr已初始化为任何内容,即:

 if (ptr != NULL)
 {
     // assume it points to something
 }

由于这是非常惯用的,因此不将指针初始化为NULL. 指针将被初始化为一个非 NULL 垃圾值,它并不真正指向任何真实的东西。最糟糕的是,上面的检查会通过,如果恰好指针中的地址是您可以合法访问的内存,则会导致更严重的问题。在某些嵌入式环境中,您可能能够访问内存的任何部分,因此您可能会意外损坏内存的随机部分或执行代码的随机部分。

于 2011-05-03T13:19:29.040 回答
11

始终初始化您的变量。

有时,您可能希望初始化为NULL,但大多数时候,您应该能够将指针初始化为它应该持有的值。尽可能晚地声明变量,并在此时初始化它们,而不是代码中的 15 行。

于 2011-05-03T13:25:22.663 回答
6

该行:

int* ptr;

绝对不能保证将指针值初始化为任何特定的值。该行:

int* ptr = NULL;

将初始化指针以指向地址零,实际上它永远不会保存任何有用的东西,并且通常会检查它是否为无效指针值。

当然,正如 Doug T. 所说,仍然有可能尝试使用该指针而不检查它,因此它仍然会崩溃。

显式初始化为 NULL 的优点是确保在将指针设置为有用的值之前取消引用指针会崩溃,这实际上是一件好事,因为它可以防止代码在掩盖严重错误的同时“意外”工作。

于 2011-05-03T13:26:01.957 回答
3

如果由于任何原因在声明发生时无法对其进行初始化,则最好将指针初始化为 NULL。例如:

Object *ptr = new Object();

通常,函数可以根据 NULL 检查指针的值,以验证指针之前是否已初始化。如果您没有将它显式设置为 NULL,并且它指向一个随机值,那么它可能会被取消引用,从而导致段错误。

于 2011-05-03T13:22:05.333 回答
2

C++ 继承于 C,因为它不是为了安全而设计的。它旨在提高效率。因此,自动变量没有被初始化。您可以确保在初始化之前不使用任何指针(尽管如果您不初始化变量,许多编译器会警告您)

于 2011-05-03T14:09:19.287 回答
1

如果不使用指针,编译器将简单地忽略它。恕我直言,将其初始化为 NULL 是安全的做法。

你确定你不会对函数声明感到困惑吗?一个函数被声明为是很常见的

char* do_something(const char* 一,const char* 二);

在这种情况下,指针用于指定要传递的参数类型。

于 2011-05-03T13:22:48.530 回答
1
int a,*ptr;

现在

print(ptr,*ptr)

在上面的代码中可能有两种情况:

  1. 如果 ptr 中的默认值不是程序的某些已用内存的地址,它将执行。

    输出:

           ptr             *ptr
    eg.  0x400730       -1992206795
    
  2. 如果 ptr 中的默认地址是程序的某些已用内存的地址,它将给出错误(段错误)。例如,如果变量 a 在内存中的地址也是 0x400730。

于 2016-01-16T12:59:48.383 回答
-1

在 C++ 中,您通常应该完全避免使用普通的旧指针。标准库类、智能指针(直到 C++0x 仅在 Boost 或 Loki 等各种库中)和引用可以而且应该在大多数地方使用。

如果你不能避免指针,确实最好用初始化来声明它们,在大多数情况下它不应该是 NULL,而是实际的目标值,因为在 C++ 中你可以自由地混合声明和表达式,所以你可以而且应该只声明变量在你有有意义的价值点。

在 C 语言中,您必须大量使用指针,并且所有变量都必须(或必须在 C99 之前;我不确定)在作用域的开头声明,情况并非如此。很多人仍然有不适合 C++ 的 C 的坏习惯。

于 2011-05-03T13:25:26.967 回答