Pregunta

he definido una clase llamada nth_best_parse de esta manera:

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

Luego declaró vectores de esta nth_best_parse como miembros de dos clases 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>
}

Luego ejecutar este programa con GDB (por cierto, estoy usando Linux Ubuntu 9.04, g ++ 4.3.3, 6.8 GNU GDB-debian) y establecer un punto de interrupción al final de la definición de compute_n_best_parses () con un poco de condiciones (para localizar la llamada exacta de esta función que quería, estaba trazando volver de un fallo de segmentación). Cuando GDB el punto de interrupción, emití un conjunto de comandos y la salida GDB era así:

(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

Línea 639 de BPCFGParser.cpp era así:

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

Este fue un macro definido al principio del archivo 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))

Por cierto, Traversal clase se define 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;}
    };

Así que en realidad estoy empujando algo a los n_best_pairs_for_traversals vector, que es un miembro de una instancia de la clase y la BPCFGParser push_back () Código de alguna manera sobrescribe en las n_best_parses vector, que es miembro de una instancia de la clase Edge . ¿Cómo puede ser posible alguna vez?

¿Fue útil?

Solución

¿Seguro que estás pasando un primer argumento válido a la macro? Tal vez usted está fuera de los límites para acceder al hacer n_best_pairs_for_traversals[x] porque x es más grande que el tamaño del vector.

Otros consejos

Es obvio que tiene problemas de corrupción de memoria en alguna parte.
Pero no es suficiente aquí la información que le ayude.

Pero usted está escribiendo código C ++ y su clase contienen punteros.
Esto no es una buena señal (hay casi siempre debe ser un puntero RAW en una clase de C ++).
Esto también es a menudo la causa de la corrupción de la memoria para los desarrolladores sin experiencia C ++!

Ha obedecido la regla de 4?

Asegúrese de que todas las clases que contiene punteros propiedad RAW:

  • constructor
  • constructor de copia
  • operador de asignación
  • destructor.

supongo que está utilizando un vector para almacenar objetos (tal vez Transversal?), Sin darse cuenta que empujar nuevos elementos al vector que puede invalidar punteros a elementos que ya están en el vector. Use un lugar deque si este es el caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top