【问题标题】:C++: Difference between setting a pointer to nullptr and initializing it as a new variable typeC++:设置指向 nullptr 的指针和将其初始化为新变量类型之间的区别
【发布时间】:2016-08-23 21:05:45
【问题描述】:

我正在学习 C++,我知道“新”关键字用于将内存中的地址分配给指针。而且我认为在使用“nullptr”时会初始化一个指向任何内容的指针。那是对的吗?参考示例:

//using nullptr
int *x = nullptr; //this is just a pointer that points to nothing and
                  //will need to be initialized with an address before it  
                  //it can be used. Correct?

//using new
int *x = new int; //this is basically giving x an address in memory. Will the 
                  //address have some residual value stored in it or will
                  //it contain zero?

您什么时候会使用其中一种? new 仅用于动态内存分配还是有其他应用程序?如果您可以声明一个指向 nullptr 的指针,然后稍后再对其进行初始化,为什么还要初始化它呢?

感谢您的帮助!

【问题讨论】:

    标签: c++ pointers new-operator nullptr


    【解决方案1】:

    您对new intint *x = new int; 的理解不正确(或者至少您的措辞不正确)。

    new int 分配一些内存。它不是“为指针分配内存”,它只是分配内存。它提供了一个指向该内存的指针,该内存以前不存在。

    int *x; 还为名为@9​​87654325@ 的变量分配内存。 x 是一个变量,其值为另一个对象的地址。 (与其他类型的变量相反,其值可以是数字或字符串等)。

    int *x = nullptr; 表示x 拥有一个称为“空指针”的特殊值,它不指示任何其他对象。

    int *x = new int 表示x 持有new int 分配的内存块的地址。所以这一行涉及到两个分配:x,以及new分配的未命名内存。

    在后一种情况下,您可以分别输出每个分配的地址,例如:

    cout << &x << ',' << x << '\n';
    

    【讨论】:

      【解决方案2】:

      是的,您对这两个作业的作用的描述通常是正确的。

      至于您为什么要初始化指向 NULL 的指针的问题,这是为了让您的代码以后可以针对 NULL 进行测试。通常的范例是,如果一个指针是 NULL,那么你知道它没有被初始化,也没有指向任何东西。如果它不是 NULL,那么它可能指向一个有效的对象,你可以使用它。尽管该范例意味着当指针指向的对象被删除或以其他方式无效时,您需要确保将指针设置回 NULL。您可能想了解智能指针的工作原理,而不是常规的“哑”指针。

      【讨论】:

        【解决方案3】:
        int *x = nullptr; 
        
        // some code here that might under some condition
        // lead to an actual object address being stored in x
        
        if (x)
        {
          // do some stuff here which is only performed if 
          // x doesn't contain a nullptr value anymore
        }
        

        并非只有当指针实际指向一个对象时,它们才发挥作用。空指针值是绝对常见的。您可以检查指针是否为 nullptr,并且该检查需要初始化指针。

        不必使用实际地址进行初始化即可使用。

        您希望像任何其他在未初始化时具有不确定值的基本类型一样初始化指针:立即给它一个有效值,而不必记住您仍然需要初始化它。

        指针变量就像任何其他基本变量一样。

        • 它驻留在具有sizeof(int*) 字节内存的堆栈上,用于存储int 类型的地址
        • 如果没有初始化器,它将不会被初始化(不确定)

        你什么时候会使用其中一个?

        第一个(nullptr):如果指针实际上可能保持为 nullptr。 第二个(new int):当你知道你实际上需要分配的整数时。

        PS:如今,原始指针实际上应该很少见(有充分的理由)。

        【讨论】:

          【解决方案4】:

          int *x = nullptr; 你说得有点对。 x 的值是nullptrnullptr 是......呃......让我们问专家:What exactly is nullptr? 反正不是什么都不是。它只是保证是一个安全的停车位,直到可以更好地使用指针。

          int *x = new int读取x指向的值,*x将是Undefined Behaviour。你可能会得到一个残值,但谁能确定呢?

          int *x = new int();阅读*x会得到0。

          int *x = new int(1000000);阅读*x将获得1000000。

          如果您没有要指出的内容,请使用nullptr 作为占位符。不要分配存储只是为了给指针一些指向的东西。这是浪费内存,浪费时间分配和解除分配,如果你忘记delete 它可能会导致内存泄漏。 nullptr 是安全的。您可以测试nullptr 并对其指向的信息的质量做出决定。如果您不确定指针是否在使用中,您可以delete nullptr 而不必担心会出现问题。

          【讨论】:

          • 第一个不会是 UB。 x 将简单地指向一个未初始化的值。使用那个未初始化的值将是 UB。
          • 迂腐:阅读*x 是未定义的行为。读取x 很好(尽管原始指针值没有多大用处)。
          • int *x = nullptr; -- xnullptr;它没有指向任何东西。
          【解决方案5】:

          你的理解是正确的。 nullptr 是一个很好的初始化值,表示没有指针指向的内存。此外,deletenullptr 的操作是安全的,而对任意值的delete 操作(这通常是您不初始化指针的情况)可能会导致分段错误。

          当使用new时,如果你想将内存初始化为零,你应该使用new int()。否则,内存可能会有残留数据。

          【讨论】:

            【解决方案6】:

            我认为在使用nullptr 时会初始化一个指向任何内容的指针。那是对的吗?您什么时候会使用其中一种?如果您可以声明一个指向 nullptr 的指针,然后稍后再对其进行初始化,为什么还要初始化它呢?

            是的。要记住的重要一点是,一旦将内存分配给指针,就必须对其进行管理。所以nullptr 是一个标记值,意味着指针不指向任何东西。

            new 仅用于动态内存分配还是有其他应用程序用于它?

            这是new唯一功能。您可以通过放置 new 来专门处理此行为,但您仍在分配内存。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-04-17
              • 2020-08-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多