奇怪的指针行为

时间:2013-08-15 17:58:06

标签: c++

采用以下结构和类:

struct TestStruct
{
};

class TestClass
{
public:
    TestStruct* testStruct;
};

main中执行以下操作:

TestClass testClass;
if (testClass.testStruct == NULL)
    cout << "It is NULL." << endl;
else
    cout << "It is NOT NULL.";

输出结果为:It is NOT NULL.

但是,如果我这样做:

TestClass testClass;
if (testClass.testStruct == NULL)
    cout << "It is NULL." << endl;
else
    cout << "It is NOT NULL." << endl << testClass.testStruct;

输出结果为:It is NULL.

有趣的是,如果我这样做(基本上和上面一样):

TestClass testClass;
if (testClass.testStruct == NULL)
{
    cout << "It is NULL." << endl;
}
else
{
    cout << "It is NOT NULL." << endl;
    cout << testClass.testStruct;
}

输出将是:

It is NOT NULL.
0x7fffee043580.

发生了什么事?

5 个答案:

答案 0 :(得分:13)

声明testClass时,您的指针未初始化。您在这里遇到了未定义的行为。指针的值将是存储它的内存部分中包含的最后一个值。

如果您希望始终NULL,则需要在班级的构造函数中对其进行初始化。

class TestClass
{
public:
    TestClass(): testStruct(NULL) {}
    TestStruct* testStruct;
};

答案 1 :(得分:4)

<强> 答案

对我而言,它会在两个问题中显示“它不是空”有时你可能会将其显示为NULL

上述情况发生的原因是C ++不会自动为变量赋值,因此它包含未知值

因此有时未知值可能为NULL,但有时可能不是

测试这个理论的最好方法是在Visual C ++和g ++以及任何其他c ++编译器中尝试它

另一个原因为你获得null或不为空的是,的编译时以不同的方式应用程序的编译器输出不同的可执行程序因此在一个未定义的变量情况下的编译器可输出一个可执行文件,在执行时可以将未定义的变量指向NULL或NOT NULL

使用GNU C ++编译器和Microsoft命令行编译器进行的测试

警告不要使用此代码IT'BAD(这是对两个编译器中未定义变量方案的测试)

代码(基于OP):

#include <iostream>
using namespace std;

struct TestStruct
{
};

class TestClass
{
public:
    TestStruct* testStruct;


};

int main(){
    TestClass testClass;
    if (testClass.testStruct == NULL)
        cout << "It is NULL." << endl;
    else
        cout << "It is NOT NULL." << endl << testClass.testStruct;
}

GNU G ++ GNU G++ test

Visual Studio CL

CL

答案 2 :(得分:3)

testStruct有时会为NULL,有时不会为NULL。

确保构造函数清除指针。 C ++中的变量不是默认为NULL / 0。

答案 3 :(得分:2)

嗯,默认情况下,指针不会被初始化。你必须在构造函数中这样做。它只包含RAM中的内容。在通常的32位系统上,它为NULL的可用性大约为0.2e-9。在64位系统(64位组件)中,它甚至更低。

答案 4 :(得分:2)

这是因为您没有初始化testStruct成员。您在此处有未定义的行为。它包含垃圾值。

如果您希望将其初始化为NULL,则可以执行以下操作:

class TestClass
{
public:
    TestClass(): testStruct(NULL) {}
    TestStruct* testStruct;
};

或使用 c ++ 11 方式:

class TestClass
{
public:
    TestStruct* testStruct{NULL}; // or TestStruct* testStruct = NULL;
};

现场的所有三个例子:http://ideone.com/ge25Zr


正如评论中所述,要完成C ++ 11方式,您可以使用nullptr

class TestClass
{
public:
    TestStruct* testStruct = nullptr; // or TestStruct* testStruct{nullptr};
};

顺便说一下,将成员属性保持私有或至少受到保护是一种更好的做法。您应该创建访问器以进行检索。