两个几乎相同的C++程序,一个运行良好,但另一个出现运行时错误

Two almost identical C++ program, one runs well but the other get runtime error

本文关键字:运行 另一个 运行时错误 一个 程序 两个 C++      更新时间:2023-10-16

比较以下两段代码:

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机器。

这真的让我很困惑。有人能告诉我原因吗?

两者都是错误的。b指针未初始化,因此您不应该通过它访问内存。

B *b;
b->val = 1;

所以当其中一个坠毁时你很幸运。

另一个你运气不好,它没有坠毁。

Fixes

您可以删除间接寻址。。。

B b;
b.val = 1;

或者你可以分配它…

std::unique_ptr<B> b(new B());
b->val = 1;

您在此处取消引用未初始化的指针

b->val = 1;

指针指向的位置尚未确定:它可以指向任何位置。

这个指针后面是未定义的行为(UB(,这意味着任何事情都可能发生,这就是您所看到的。

真正发生的事情是,你正在向一段内存写入一个不应该写入的值。没有办法知道那里有什么,C++标准也不能对可能的结果做出任何承诺。它只是称之为UB。避免这些情况由你决定。

问题是您使用的是一个未初始化的指针:B* b;。在C和C++中,内置类型在创建时不会初始化:它们只是包含垃圾。

解决问题的方法很简单:不要使用指针。B b;将创建一个类实例并调用其构造函数。

代码#1运行良好,但代码#2出现运行时错误。

用标准化的说法,这两个代码都表现出未定义的行为。这意味着几乎任何事情都可能发生,这包括似乎在工作(即,可能存在错误,但没有明显的症状(。

在使用任何指针之前,都需要初始化它。你看到的是所谓的未定义行为。

#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;
}

b->val指向一个无效的内存位置。在分配b->val 之前为b分配内存