Frage

I definiert eine Klasse nth_best_parse diese Weise benannt:

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

Dann erklärte ich Vektoren diese nth_best_parse als Mitglieder von zwei verschiedenen Klassen:

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

Dann laufe ich dieses Programm mit GDB (übrigens, ich bin mit Linux Ubuntu 9.04, g ++ 4.3.3, GNU gdb 6.8-debian) und einen Haltepunkt am Ende der Definition von compute_n_best_parses () mit einigen gesetzt Bedingungen (den genauen Aufruf dieser Funktion zu finden, ich wollte, ich wurde von einer Segmentierung Fehlersuche zurück). Wenn gdb den Haltepunkt erreicht, gab ich eine Reihe von Befehlen und der GDB Ausgang war wie folgt:

(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

Linie 639 von BPCFGParser.cpp war wie folgt:

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

Dies war ein Makro am Anfang der Datei wie folgt definiert:

#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))

Durch die Art und Weise, Klasse Traversal ist wie folgt definiert:

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

Also eigentlich etwas zu dem Vektor n_best_pairs_for_traversals Ich bin drängen, die ein Mitglied einer Instanz der Klasse BPCFGParser ist und die push_back () Code irgendwie überschreibt auf dem Vektor n_best_parses, die ein Mitglied einer Instanz der Klasse Edge . Wie kann dies jemals möglich sein?

War es hilfreich?

Lösung

Sind Sie sicher, dass Sie ein gültiges erstes Argument für Ihren Makro vorbei sind? Vielleicht sind Sie den Zugriff von Grenzen, wenn n_best_pairs_for_traversals[x] tun, weil x größer als die Vektorgröße ist.

Andere Tipps

Sie haben offensichtlich Speicher Korruption Probleme irgendwo.
Aber es gibt nicht genug hier Informationen, Ihnen zu helfen.

Aber Sie schreiben, C ++ Code und Ihre Klasse enthalten Zeiger.
Dies ist kein gutes Zeichen (es sollte so gut wie nie ein RAW-Zeiger in einer C ++ Klasse).
Dies ist auch oft die Ursache für Speicherfehler für unerfahrene C ++ Entwickler!

Haben Sie die Regel von 4 befolgt?

Stellen Sie sicher, jede Klasse, die RAW Besitz Zeiger enthält:

  • Konstruktor
  • Copykonstruktor
  • Zuweisungsoperator
  • destructor.

Ich würde vermuten, dass Sie einen Vektor verwenden Objekte zu speichern (vielleicht Traversal?), Nicht ahnend, dass drängen neue Elemente auf diesen Vektor Zeiger auf Elemente, die bereits in dem Vektor ungültig machen kann. Verwenden Sie einen deque statt, wenn dies der Fall ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top