理解指向Object的指针设置为NULL的问题

时间:2011-07-28 07:55:02

标签: c++ class

任何人都可以通过将指向对象的指针解释为NULL来解释它是什么意思吗?

当我们将对象的ptr分配给NULL时,我们如何才能访问成员函数?

class A
{
public:
    void print()
    {
        cout<<"Hello";
    }
}

int main()
{
    A * a;
    A* b = NULL;

    a->print();
    b->print();
}

修改 程序会崩溃吗? http://ideone.com/DudZ6

3 个答案:

答案 0 :(得分:5)

指针用于访问该对象的成员。如果您的函数不需要访问任何成员而不是虚拟成员,则它们实际上不使用该对象。严格来说代码仍然无效,但不会崩溃。

如果用打印“this”指针替换内容,它仍然可以正常工作,因为你没有取消引用它。

struct X { 
    void print() { 
        cout << "this pointer is " << this << endl; 
    } 
};

int main() {
    X *x;
    x->print(); // will print whatever was on the stack, ie, random garbage
    X *t = NULL;
    t->print(); // will print a null pointer
}

如果添加一个成员变量并将其打印出来,或者将该函数设置为虚拟(因此必须通过对象本身进行查找),它将会崩溃。

struct X { 
    virtual void print() { 
        cout << "Hello World" << endl; 
    } 
};

struct X2 { 
    int y;
    void print() { 
        cout << "y is " << y << endl; 
    } 
};

int main() {
    X *x = NULL;
    x->print(); // will crash on null pointer dereference
    X2 *x2 = NULL;
    x2->print(); // will crash on null pointer dereference
}

答案 1 :(得分:5)

你做不到。任何取消引用指针的尝试(任何应用程序) 它的*->运算符是未定义的行为,可能会这样做 任何东西。当然,大多数情况下,你只会崩溃 代码实际上需要来自对象的数据(包括像a这样的内部数据) vptr);否则,代码似乎工作。但那只是其中之一 可能的未定义行为;我实际上使用了编译器 你的小程序会崩溃。


根据 C ++标准

1.9程序执行
4:

本国际标准中将某些其他操作描述为未定义(,例如,取消引用空指针的效果)。 [注意:本国际标准对包含未定义行为的程序的行为没有要求。 ]

严格地说,行为是未定义的,正如许多人在评论部分中指出的那样仅仅是因为它在特定平台上工作并不能使其合法化。

因此根据C ++标准,代码段的行为是未定义行为。

答案 2 :(得分:1)

你不能,

   A* b = NULL;
 b->print();

这是 undefined bahvior ,可能会导致程序崩溃segmentation fault(取决于print方法的定义)。

一般来说,为指针赋值NULL用于为指针赋予一个值,表示“此指针未设置,不使用它”。拿这个代码:

void function() {
   int* p;
   int* q = NULL:
   ... 
}

调用该函数时,在堆栈上分配pq;由于编译器的工作方式,p保持未分配状态,这意味着它在调用函数时获取在堆栈中找到的值;这是一个随机值,通常与您的程序没什么关系。

现在,p有一个值的事实可能会让你认为这个值是“正确的”,所以你使用它;但是,它不是(因为它是随机的,由于没有初始化指针),所以你也会遇到崩溃或某种意外行为。

q的情况下,为其分配NULL的事实允许您告知它没有可用的值。所以,你没有参考它:

 if (q != NULL) {
     q->....
 }

上面的成语对p不起作用,所以你无法判断它是否正常。

最后:总是初始化你的变量;在指针的情况下,如果你没有要分配的值,请指定NULL,因此你知道不应该取消引用指针。