比较以下两段代码:
1
#include <iostream>
using namespace std;
class B{
public:
int val;
};
int main(){
B *b;
int t = 0;
b->val = 1;
cout << 123 << endl;
return 0;
}
2
#include <iostream>
using namespace std;
class B{
public:
int val;
};
int main(){
B *b;
b->val = 1;
cout << 123 << endl;
return 0;
}
两个版本都编译。代码#1运行良好,但代码#2运行错误。
我正在使用C ++ 11编译并运行Windows机器。
这让我很困惑。谁能告诉我原因?
答案 0 :(得分:14)
两者都错了。 b
指针未初始化,因此您不应通过它访问内存。
B *b;
b->val = 1;
当其中一人坠毁时,你很幸运。
另一个你运气不好,并没有崩溃。
您可以删除间接...
B b;
b.val = 1;
或者你可以分配它......
std::unique_ptr<B> b(new B());
b->val = 1;
答案 1 :(得分:4)
您在这里取消引用未初始化的指针
b->val = 1;
指针指向的位置未确定:它可能指向任何位置。
在此指针之后是未定义的行为(UB),这意味着任何事情都可能发生,这就是您所看到的。
真正发生的是你正在为一段你不应该写的内存写一个值。没有办法知道那里有什么,而且C ++标准对可能的结果没有任何承诺。它只是称这个UB。你应该避免这些情况。
答案 2 :(得分:1)
您需要在使用之前初始化任何指针。 你看到的是所谓的未定义行为。
#include <iostream>
using namespace std;
class B{
public:
int val;
};
int main(){
B *b = new B();
int t = 0;
b->val = 1;
cout << 123 << endl;
delete b;
return 0;
}
应该和
一样好用#include <iostream>
using namespace std;
class B{
public:
int val;
};
int main(){
B b;
int t = 0;
b.val = 1;
cout << 123 << endl;
return 0;
}
答案 3 :(得分:1)
问题是您使用的是未初始化的指针:B* b;
。在C和C ++中,内置类型在创建时不会被初始化:它们只是持有垃圾。
解决问题的方法很简单:不要使用指针。 B b;
将创建一个类实例并调用其构造函数。
代码#1运行良好,但代码#2运行错误。
在Standardese的说法中,两个代码都显示未定义的行为。这意味着几乎任何事情都可能发生,并且包含看似正常工作(即,可能存在错误,但没有明显的症状)。
答案 4 :(得分:0)
b->val
指向无效的内存位置。在分配b
b->val
分配内存