0

セグメンテーション違反はスキャナーコードで発生します。

問題:

GDBを使用してバックトラックすると、条件:if()で(ここで、は)FieldInfoという名前のポインターの宣言で問題が発生していることがわかります。field_infoFieldInfostructtell_me

次のコードは大きなファイルの一部であることに注意してください。したがって、ここに宣言がないものがある場合は、それらがプログラムの別の場所で定義されており、ここには表示されていない可能性があります。

サンプルコード:

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);
}

};

分析:

解析は、パーサーを呼び出すメソッドです。

field_infoGDBは、パーサーがを繰り返し処理しようとすると、問題(セグメンテーション違反)が発生することを明らかにし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)部分を追加し、他のすべてはすでにそこにありました。

4

1 に答える 1

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_objpos_prefixアドレスが無効になるため、スコープ外になった後はこのアドレスにアクセスしないようにする必要があります。

コードに非常に多くの生のポインターが含まれています。これは、最新のC++では適切な方法ではありません。プレーンオブジェクト、参照、またはスマートポインタの使用を検討してください。

于 2012-08-15T08:22:58.230 に答える