我正在使用解析器,而且我遇到了麻烦的段错误。
解析器返回一个已解析的变体,该变体又返回用于传递解析结果的变体。删除指向基类的指针时会发生段错误。
这是我的基类:
class ParsedVariant {
protected:
ParsedVariant() {}
public:
virtual ~ParsedVariant() {}
private:
ParsedVariant(const ParsedVariant& other);
ParsedVariant& operator= (const ParsedVariant& other);
public:
virtual const std::string& getName() const=0;
// Get the final variant.
virtual Variant *getVariant()=0;
};
这是模板化的子类:
template<typename S, class V> class ParsedScalar : public ParsedVariant {
public:
ParsedScalar(const S& s, const std::string& n) : sval(s), name(n) {}
~ParsedScalar() {}
private:
ParsedScalar(const ParsedScalar& other);
ParsedScalar& operator= (const ParsedScalar& other);
public:
const std::string& getName() const { return name; }
Variant *getVariant() { return new V(sval, name); }
private:
S sval;
std::string name;
};
S模板参数将是标量类型(int,bool,double等)。 V模板参数将是最终的变体类。
它们的用法如下:
ParsedVariant *functionA() {
int n;
// Some work here.
return new ParsedScalar<int, IntegerVariant>(n, "varname");
}
void functionB() {
ParsedVariant *var = functionA();
// Do some work.
delete var; <== SEGV happens here.
}
在基础调用free中的ParsedVariant析构函数中发生了段错误。我在模板中使用哪种标量类型并不重要,它们都是段错误。编译器是g ++ 4.8.3,我使用-std = c ++ 11标志。我觉得这很明显,但我似乎错过了它。任何帮助表示赞赏。
答案 0 :(得分:0)
我解决了问题,但原因很奇怪;
class ScalarParser {
public:
ScalarParser();
~ScalarParser();
public:
ParsedVariant *getParsed() { return parsed; }
void parse(std::istream& in); // Produces parsed
private:
ParsedVariant *parsed;
};
ScalarParser::~ScalarParser() {
delete parsed;
}
void Document::parseScalar(std::istream& in) {
ScalarParser parser;
parser.parse(in); <== produces valid ParsedVariant
ParsedVariant *parsed = parser.getParsed(); <== ~ScalarParser called after this line
push(parsed->getVariant()); <== SEGV
}
如果我在ScalarParser析构函数中注释掉删除,则段错误就会消失。这也使得段错误消失了。
void Document::parseScalar(std::istream& in) {
ScalarParser *parser = new ScalarParser;
parser->parse(in);
ParsedVariant *parsed = parser->getParsed();
push(parsed->getVariant());
delete parser;
}
这也纠正了这个问题。
void Document::parseScalar(std::istream& in) {
std::unique_ptr<ScalarParser> parser(new ScalarParser);
parser->parse(in);
ParsedVariant *parsed = parser->getParsed();
push(parsed->getVariant());
}
这是一个解析器,因此代码很大且复杂。其中一些也是专有的,所以这是我能做的最好的。我不确定这是否是编译器错误。我会继续戳它以获取更多信息。感谢您的回复。