Pergunta

I definida uma classe chamada nth_best_parse desta maneira:

class nth_best_parse {
      public:
        int traversal;
        int nth_best_active;
        int nth_best_passive;
        double viterbi_prob;

        nth_best_parse();
        nth_best_parse(int t, int nbl, int nbr, double v) {traversal = t; nth_best_active = nbl; nth_best_passive = nbr; viterbi_prob = v;}
    };

Então eu declarou vetores desse nth_best_parse como membros de duas classes diferentes:

class Edge {        // an edge associates an Earley style dotted-item with a span
      public:

        <some irrelevant stuff>

        Span span;      // Span of the edge
        bool isActive;
        vector<Traversal *> leading_traversals; // The list of traversals which lead to parsing of this edge

        vector<nth_best_parse> n_best_parses;


        union {
                DottedRule rule_state;  // Accessed if isActive is true
                int symbol;     // Accessed if isActive is false
                                // A symbol corresponding to the category of a passive edge
                                // Put inside this union to save space
        };

        inline int span_length() {return span.end - span.start;}

    };

<some other stuff>

class BPCFGParser {

  public:

    // Some data structures used in intermediary computations for calculating the n-best parses

//    vector<vector<int> > nth_best_pairs;
    vector<vector<nth_best_parse> > n_best_pairs_for_traversals;

    <some other stuff>

    void compute_n_best_parses(Edge *e, int n);

    <some other stuff>
}

Então eu executar este programa com gdb (a propósito, estou usando o Linux Ubuntu 9.04, g ++ 4.3.3, GNU gdb 6.8-debian) e defina um ponto de interrupção no final da definição de compute_n_best_parses () com alguma condições (para localizar a chamada exata desta função que eu queria, eu estava traçando voltar de uma falha de segmentação). Quando gdb atingido o ponto de interrupção, I emitiu um conjunto de comandos ea saída gdb foi assim:

(gdb) print e->n_best_parses.size()
$27 = 1
(gdb) print e->n_best_parses[0]
$28 = (nth_best_parse &) @0x1e96240: {traversal = 0, nth_best_active = 0, nth_best_passive = 0, viterbi_prob = 0.16666666666666666}
(gdb) print e->n_best_parses[0].traversal
$29 = 0
(gdb) print &(e->n_best_parses[0].traversal)
$30 = (int *) 0x1e96240
(gdb) awatch *$30
Hardware access (read/write) watchpoint 6: *$30
(gdb) print e->n_best_parses
$31 = {<std::_Vector_base<nth_best_parse, std::allocator<nth_best_parse> >> = {
    _M_impl = {<std::allocator<nth_best_parse>> = {<__gnu_cxx::new_allocator<nth_best_parse>> = {<No data fields>}, <No data fields>}, 
      _M_start = 0x1e96240, _M_finish = 0x1e96258, _M_end_of_storage = 0x1e96288}}, <No data fields>}
(gdb) continue
Continuing.
Hardware access (read/write) watchpoint 6: *$30

Old value = 0
New value = 1
0x0000000000408a4c in __gnu_cxx::new_allocator<nth_best_parse>::construct<nth_best_parse> (this=0x1e96208, __p=0x1e96240, __args#0=@0x7fff8ad82260)
    at /usr/include/c++/4.3/ext/new_allocator.h:114
114     { ::new((void *)__p) _Tp(std::forward<_Args>(__args)...); }
(gdb) backtrace
#0  0x0000000000408a4c in __gnu_cxx::new_allocator<nth_best_parse>::construct<nth_best_parse> (this=0x1e96208, __p=0x1e96240, __args#0=@0x7fff8ad82260)
    at /usr/include/c++/4.3/ext/new_allocator.h:114
#1  0x000000000042169c in std::vector<nth_best_parse, std::allocator<nth_best_parse> >::push_back<nth_best_parse> (this=0x1e96208, __args#0=@0x7fff8ad82260)
    at /usr/include/c++/4.3/bits/stl_vector.h:703
#2  0x0000000000402bef in BPCFGParser::compute_n_best_parses (this=0x7fff8ad82770, e=0x7f5492858b78, n=3) at BPCFGParser.cpp:639
#3  0x00000000004027fd in BPCFGParser::compute_n_best_parses (this=0x7fff8ad82770, e=0x7f5492859d58, n=3) at BPCFGParser.cpp:606
#4  0x00000000004027fd in BPCFGParser::compute_n_best_parses (this=0x7fff8ad82770, e=0x7f549285a1d0, n=3) at BPCFGParser.cpp:606
#5  0x00000000004064d8 in main () at experiments.cpp:75

Linha 639 de BPCFGParser.cpp era assim:

PUSH_BEST_PAIR_FOR_TRAVERSAL(i,row,column,grammar->probs[temp_rule.symbol][temp_rule.expansion]);

Este era um macro definido no início do arquivo como:

#define PUSH_BEST_PAIR_FOR_TRAVERSAL(x,y,z,t) n_best_pairs_for_traversals[x].push_back(nth_best_parse(x, y, z, e->leading_traversals[x]->active_edge->n_best_parses[y].viterbi_prob * e->leading_traversals[x]->passive_edge->n_best_parses[z].viterbi_prob * t))

A propósito, classe Traversal é definido como:

class Traversal {   // Class for a traversal
      public:
        Edge *active_edge;
        Edge *passive_edge;
        Traversal();
        Traversal(Edge *a, Edge *p) {active_edge = a; passive_edge = p;}
    };

Então na verdade eu estou empurrando algo para os n_best_pairs_for_traversals vetor, que é um membro de uma instância da classe BPCFGParser e push_back () código de alguma forma substitui nas n_best_parses vetor, que é membro de uma instância da classe borda . Como isso pode nunca ser possível?

Foi útil?

Solução

Você tem certeza de que você está passando um primeiro argumento válido para o macro? Talvez você está acessando fora dos limites ao fazer n_best_pairs_for_traversals[x] porque x é maior do que o tamanho do vetor.

Outras dicas

Você obviamente tem problemas de corrupção de memória em algum lugar.
Mas não é suficiente aqui informações para ajudá-lo.

Mas você está escrevendo código C ++ e sua classe contêm ponteiros.
Este não é um bom sinal (há quase nunca deve ser um ponteiro RAW em uma classe C ++).
Esta é também frequentemente a causa de corrupção de memória para desenvolvedores inexperientes C ++!

Você obedeceu à regra de 4?

Certifique-se de cada classe que contém RAW propriedade ponteiros:

  • construtor
  • construtor de cópia
  • operador de atribuição
  • destructor.

Eu acho que você está usando um vetor para armazenar objetos (talvez Traversal?), Não percebendo que empurrando novos elementos para que vector pode invalidar ponteiros para elementos já no vetor. Use um deque em vez se este for o caso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top