为什么在C 类构造函数的正确编译后发生运行时错误

Why runtime error happened after right compiling for c++ class constructor

本文关键字:编译 运行时错误 构造函数 为什么      更新时间:2023-10-16

当我运行 ./out时,它会引发错误的通知:

[1]    66798 segmentation fault  ./a.out

,但它可以通过编译器而不会出错:

clang++ -std=c++11 -g test.cpp

这样的代码,我发现它在GDB附近靠近hobby->push_back(hb)

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;
struct X {
public:
    X(const string &, const unsigned, const string &);
    X(const X &);
    X &operator=(const X &);
    ~X();
    void print();
private:
    string name;
    unsigned age;
    shared_ptr<vector<string>> hobby;
};
X::X(const string &nm, const unsigned ae, const string &hb):
    name(nm), age(ae)
{
    hobby->push_back(hb);
    cout << "X()" << endl;
}
X::X(const X &obj)
{
    cout << "X(const X &obj)" << endl;
}
X &X::operator=(const X &obj)
{
    cout << "X::operator=(const X &obj)" << endl;
    return *this;
}
X::~X()
{
    cout << "~X()" << endl;
}
void X::print()
{
    cout << "name: " << name << 'n'
        << "age: " << age << 'n';
    for (auto const &hb : *hobby) {
        cout << hb << ' ';
    }
    cout << endl;
}
int main()
{
    X a = ("bjcharles", 30, "swimming");
    a.print();
    return 0;
}

您有一个共享指针:

shared_ptr<vector<string>> hobby;

您通过执行以下方式退出:

hobby->push_back(hb);

这是不确定的行为,因为您从未分配给shared_ptrstd::vector实例,因此您可能正在删除null指针。未定义的行为意味着任何事情都可能发生,包括它的工作,或者在您的情况下是细分故障。

您需要:

  1. 创建内存,最好是在初始化列表下的构造函数中:

    X::X(const X &obj) : hobby(std::make_shared<std::vector<...( ...

  2. 不要为此使用smart_ptr。std::vector已经是一种很棒的RAII类型。除非您需要共享此指针(从您的班级定义中,您只能直接使用std::vector(无包含shared_ptr(。


作为最后的注意,这应该可以帮助您意识到您不能依靠编译器来检查您的代码。仅仅因为编译并不意味着它会起作用。例如,这将编译:

int arr[5];
arr[6] = 5;

,但这绝不意味着这是正确的或安全的,并且不会导致运行时错误。这仅表示它编译。