使用字符串文字时的C ++内存损坏

时间:2018-03-13 01:13:15

标签: c++ c++11

我是C ++的新手,并编写了一个小程序来了解有关OOD和多态的更多信息。

总之,我有一个基类(WeeklyCompCalculator),它包含一个成员变量(string description),它通过派生类(FixedCompCalculator)中的构造函数调用传入。 / p>

当我使用const string(FIXED_SCHEME)初始化基类时,一切正常:

FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator(FIXED_SCHEME) {}

image

但是,当我尝试使用字符串文字进行初始化时,描述成员已损坏:

FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator("$600 Weekly") {}

image

我在下面列出了相关的代码。一个有趣的观察是,如果我修改shoe_comp.cpp使用原始指针而不是shared_ptrs,问题就会消失。

comp_calculator.h

namespace ShoeCompUtil {
  const string FIXED_SCHEME = "$600 Weekly";
  class WeeklyCompCalculator {
  public:
    WeeklyCompCalculator(const string&);
    virtual ~WeeklyCompCalculator();
    virtual double calculate( const int shoePrice, const int weeklyHours, const int weeklyUnits ) const = 0;
    string getDescription() const;
  private:
    const string& description;
  };

  class FixedCompCalculator : public WeeklyCompCalculator {
  public:
    FixedCompCalculator();
    virtual double calculate( const int shoePrice, const int weeklyHours, const int weeklyUnits ) const;
  };
};

comp_calculator.cpp

WeeklyCompCalculator::WeeklyCompCalculator(const string& descr): description{descr} {}
WeeklyCompCalculator::~WeeklyCompCalculator(){}
string WeeklyCompCalculator::getDescription() const {
  const string descr{description};
  return descr;
}

FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator("$600 Weekly") {}
double FixedCompCalculator::calculate( const int shoePrice, const int weeklyHours, const int weeklyUnits ) const 
{ 
  return 600; 
}

shoe_comp.cpp

cout << "Computing best compensation scheme given shoe_price = " << shoePrice << ", weeklyHours = " << weeklyHours << ", weeklyUnits = " << weeklyUnits << endl;
vector<shared_ptr<WeeklyCompCalculator>> calculators { make_shared<FixedCompCalculator>(), make_shared<HybridCompCalculator>(), make_shared<CommissionCompCalculator>() };
double maxComp = -1;
string maxDescr = "";
for( const shared_ptr<WeeklyCompCalculator>& calc : calculators ){
  double compHere = calc->calculate( shoePrice, weeklyHours, weeklyUnits );
  if( compHere > maxComp ){
    maxComp = compHere;
    maxDescr = calc->getDescription();
  }
}
cout << "Optimal compensation scheme is " << maxDescr << ", weekly comp = " << maxComp << endl;

1 个答案:

答案 0 :(得分:2)

派生类构造函数将字符串文字传递给基类:

FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator("$600 Weekly") 

基类的构造函数将const std::string &作为其构造函数的参数。

WeeklyCompCalculator(const string&);

因为您的参数实际上是字符串文字,所以构造 临时 std::string对象,并将对它的引用传递给基类的构造函数。

基类构造函数将其接收的引用作为其参数,并将其保存为其类的成员。

因为类成员最终成为对临时对象的引用,所以只要派生类完成构造(稍早一些,迂腐正确,但这里不相关),临时对象就会被破坏,而基础class最终会引用一个被破坏的对象,并从该点开始使用这个引用导致未定义的行为。

最简单的解决方法是让WeeklyCompCalculator的类成员成为显式对象实例,而不是引用:

  private:
    const string description;
  };

现在,只要其类的实例存在,description类成员就会保证存在。