当我运行./out
时,它会抛出错误通知:
[1] 66798 segmentation fault ./a.out
但它可以无错误地传递编译器:
clang++ -std=c++11 -g test.cpp
像这样的代码,我发现它在hobby->push_back(hb)
附近被gdb打破了。
#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;
}
答案 0 :(得分:5)
你有一个共享指针:
shared_ptr<vector<string>> hobby;
您可以通过以下方式取消引用:
hobby->push_back(hb);
这是未定义的行为,因为您从未将shared_ptr
的实例分配给std::vector
,因此您可能取消引用null
指针。未定义的行为意味着任何可能发生的事情,包括它的工作或在您的情况下,分段错误。
您需要:
创建内存,最好在初始化列表下的构造函数中:
X::X(const X &obj) :
hobby(std::make_shared<std::vector<...( ...
不要使用smart_ptr。 std::vector
已经是一个很棒的RAII类型。除非你需要分享这个指针(你的类定义中你没有),然后直接使用std::vector
(没有包围shared_ptr
)就可以了。
作为最后一点,这应该可以帮助您意识到您不能依赖编译器来检查您的代码。仅仅因为编译的东西并不意味着它会起作用。例如,这将编译:
int arr[5];
arr[6] = 5;
但这绝不意味着这是正确或安全的,并且不会导致运行时错误。它只意味着它编译。</ p>