如果指针设置为 NULL,则对它的任何引用都不会或通过它也是 NULL

If a pointer is set to NULL wouldn't any references to it or through it also be NULL

本文关键字:NULL 引用 设置 指针 如果 任何      更新时间:2023-10-16

如果指针设置为 NULL,则对它的任何引用或通过它也不会为 NULL。下面是一个可编译的示例,当您尝试运行它时会爆炸:

#include <string>
#include <iostream>
#define NULL 0
class Seedcoat {
public:
    //Seedcoat();
    std::string Name;
    int Weight;
};
class Seed {
public:
    //Seed();
    std::string Name;
    int Weight;
    Seedcoat* ItsSeedcoat;
};
class Apple {
public:
    //Apple();
    std::string Name;
    int Weight;
    Seed* ItsSeed;
};
int main()
{
///////Apple Objects Begin///////
    Apple       MyApple;
    Seed        MySeed;
    Seedcoat    MySeedCoat;
    MyApple.ItsSeed = &MySeed;
    MyApple.ItsSeed->ItsSeedcoat = &MySeedCoat;
    MyApple.ItsSeed->ItsSeedcoat->Weight = 2;
    if ( MyApple.ItsSeed != NULL) {
        std::cout << "The weight of the apple seed's seedcoat is " << MyApple.ItsSeed->ItsSeedcoat->Weight <<".n";
    }
    MyApple.ItsSeed = NULL;
    if ( MyApple.ItsSeed->ItsSeedcoat != NULL) {
        std::cout << "The weight of the apple seed's seedcoat is " << MyApple.ItsSeed->ItsSeedcoat->Weight <<".n";
    }
    return 0;
}

所以我的问题是:为什么会这样

MyApple.ItsSeed->ItsSeedcoat != NULL

返回 true。我认为不会,因为ItsSeed设置为NULL-但它仍然试图引用ItsSeedcoat的权重值-然后它轰炸了我认为是因为ItsSeed不存在。我意识到有简单的方法可以解决这个问题 - 这个例子只是为了展示我观察到的行为。这有什么值得担心的吗?- 或者这是正常行为?这样做的原因是什么?谢谢。

C++不会以这种方式握住你的手。将指针设置为 null 只会将该指针设置为 null。它不会清除任何子对象或释放任何内存,就像你在 Java 或 Python 中期望的那样。

将指针设置为 null 后,访问MyApple.ItsSeed->ItsSeedcoat就不再合法,因此任何事情都可能发生。

在你的特定问题中,我认为作文可能是一个更好的解决方案。但是,如果您确实需要C++管理内存分配/释放,我强烈建议您使用适当的智能指针,它为您提供与其他语言中的垃圾收集器大致相等的能力。

我还建议不要自己定义NULL因为某些标头已经为 C 定义了它。在 C++03 中,我通常建议使用文字0而在 C++11 中,您可以使用 nullptr 关键字。

MyApple.ItsSeed设置为 NULL 后,不允许取消引用指针MyApple.ItsSeed,这意味着不允许表达式 MyApple.ItsSeed->ItsSeedcoat

这不一定会引发异常,但其行为是未定义的。

这是未定义的行为,任何事情都可能发生。

特别是,

MyApple.ItsSeed = NULL;
if ( MyApple.ItsSeed->ItsSeedcoat != NULL)

不允许取消引用 NULL 指针。就这么简单。如果这样做,则任何行为都是合规的。

取消引用 NULL 指针会导致未定义的行为。为了到达成员ItsSeedCoat你必须取消引用指针ItsSeed,你已经将其设置为 NULL。

在您的示例中,您将 MyApple.ItsSeed(一个 Seed* 设置为 NULL),然后在执行 MyApple.ItsSeed->ItsSeedcoat 时,您尝试取消引用 NULL 指针。

将指针设置为 null 后,对该指针的任何引用也为空。 但是,在您的代码中,您没有引用到指针;你有两个完全不同的指针对象,你对一个人所做的对另一个没有影响。 (这是在我所知道的每种语言中都是如此。

C++ 不实现您所描述的行为类型。 在某些语言中,对象会跟踪指向它的所有"弱"指针,以便在释放该对象时,所有这些指针都会自动变为 NULL。 然而,C++不是这些语言之一。 释放对象时,指向该对象的指针不会自动变为 NULL。 当指向某个对象的特定指针变为 NULL 时,指向同一对象的其他指针不会自动变为 NULL。 如果您需要这种行为,请查看boost::weak_ptrstd::weak_ptr