分段错误是由扫描程序代码引起的。
使用GDB回溯显示问题是由FieldInfo
名为field_info
的指针(其中FieldInfo
为struct
)的声明引起的: (tell_me
)。
请注意以下代码是大文件的一部分,所以如果有一些声明不在这里的东西,你可以假设它们已经在程序中的其他地方被定义而没有在这里显示。 / p>
Some_function(some_arguments) {
// Did something.
if (flag_1) {
list<const FieldInfo *> prefix_stack;
const FieldInfo def_pfx(NON_BOOLEAN, default_prefix);
{
const FieldInfo * default_field_info = &def_pfx;
if (default_prefix.empty()) {
map<string, FieldInfo>::const_iterator f = field_map.find("");
if (f != field_map.end()) default_field_info = &(f->second);
}
// We always have the current prefix on the top of the stack.
prefix_stack.push_back(default_field_info);
}
// Did something.
for (<some conditions>) {
bool tell_me = false;
// Did something.
if (tell_me) {
const FieldInfo pos_prefix(NON_BOOLEAN, pos);
const FieldInfo * field_info = &pos_prefix;
Term * term_obj = new Term(&state, term_lowercase, field_info,
term, stem_term, term_pos++);
Parse(pParser, token, term_obj, &state);
} else {
const FieldInfo * field_info = prefix_stack.back();
Term * term_obj = new Term(&state, term_lowercase, field_info,
term, stem_term, term_pos++);
Parse(pParser, token, term_obj, &state);
}
// Did something.
}
}
// Did something.
}
FieldInfo
的定义是:
struct FieldInfo {
/// The type of this field.
filter_type type;
/// Field prefix strings.
list<string> prefixes;
/// Field processors struct already defined earlier.
list<FieldProcessor*> procs;
FieldInfo(filter_type type_, const string & prefix)
: type(type_)
{
prefixes.push_back(prefix);
}
FieldInfo(filter_type type_, FieldProcessor *proc)
: type(type_)
{
procs.push_back(proc);
}
};
Parse是一种调用Parser的方法。
GDB显示问题(分段错误)是在解析器尝试通过迭代field_info
来处理field_info->prefixes
时引起的。
以下是发生分段错误的函数的代码(为了调试目的,我添加了一些cout)。问题来自while(++ piter!= prefixes.end())部分代码:
Query get_query() const
{
const list<string> & prefixes = field_info->prefixes;
if (prefixes.empty()) {
assert(!field_info->procs.empty());
return (**field_info->procs.begin())(name);
}
list<string>::const_iterator piter = prefixes.begin();
Query q(make_term(*piter), 1, pos);
while (++piter != prefixes.end()) {
string check3 = make_term(*piter);
Query q2(check3, 1, pos);
q = Query(Query::OP_OR, q, q2);
}
return q;
}
我正在研究其他人的工作代码。
我添加了if(flag_1)部分代码,其他所有内容都已经存在。
答案 0 :(得分:1)
这部分看起来很可疑:
const FieldInfo pos_prefix(NON_BOOLEAN, pos);
const FieldInfo * field_info = &pos_prefix;
Term * term_obj = new Term(&state, term_lowercase, field_info,
term, stem_term, term_pos++);
您正在使用本地变量pos_prefix
的地址来初始化term_obj
。您必须确保在pos_prefix
超出范围后永远不会访问此地址,因为该地址将无效。
你的代码中有很多原始指针。这在现代C ++中并不是一个好习惯。考虑使用普通对象,引用或智能指针。