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

时间:2012-12-05 22:04:05

标签: c++ oop object null

如果指针设置为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不存在。我意识到有很简单的方法可以解决这个问题 - 这个例子只是为了显示我正在观察的行为。这有什么值得关注的吗? - 或者这是正常行为吗?这样做的原因是什么?感谢。

7 个答案:

答案 0 :(得分:3)

C ++不会以这种方式牵着你的手。将指针设置为null仅将该指针设置为null。它不会像Java或Python中那样清除任何子对象或释放任何内存。

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

在您的特定问题中,我认为构图可能是更好的解决方案。但是,如果你确实需要在C ++中管理内存分配/释放,我强烈建议你使用一个合适的智能指针,它会给你的功率大约等于其他语言的垃圾收集器。

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

格外,

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

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

答案 3 :(得分:0)

取消引用NULL指针会导致未定义的行为。为了访问成员ItsSeedCoat,您必须取消引用已设置为NULL的指针ItsSeed

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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