J'ai défini une classe nommée nth_best_parse de cette manière :
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;}
};
Ensuite, j'ai déclaré des vecteurs de cet nth_best_parse en tant que membres de deux classes différentes :
class Edge { // un edge associe un élément pointé de style Earley avec une étendue
public:
Span span; // Span de l'edge
bool isActive;
vector leading_traversals; // La liste des traversées qui mènent à l'analyse de cet edge
vector n_best_parses;
union {
DottedRule rule_state; // Accédé si isActive est vrai
int symbol; // Accédé si isActive est faux
// Un symbole correspondant à la catégorie d'un edge passif
// Mis à l'intérieur de cette union pour économiser de l'espace
};
inline int span_length() {return span.end - span.start;}
};
class BPCFGParser {
public:
// Certaines structures de données utilisées dans des calculs intermédiaires pour calculer les meilleures analyses n
// vector > nth_best_pairs;
vector > n_best_pairs_for_traversals;
void compute_n_best_parses(Edge *e, int n);
}
Ensuite, j'ai exécuté ce programme avec gdb (au fait, j'utilise Linux Ubuntu 9.04, g++ 4.3.3, GNU gdb 6.8-debian) et j'ai placé un point d'arrêt à la fin de la définition de compute_n_best_parses() avec quelques conditions (pour localiser l'appel exact de cette fonction que je voulais, je remontais à partir d'une erreur de segmentation). Lorsque gdb a atteint le point d'arrêt, j'ai lancé une série de commandes et la sortie gdb était ainsi :
(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 = { >> = {
_M_impl = {> = {<__gnu_cxx::new_allocator> = {}, },
_M_start = 0x1e96240, _M_finish = 0x1e96258, _M_end_of_storage = 0x1e96288}}, }
(gdb) continue
Continuing.
Hardware access (read/write) watchpoint 6: *$30
Ancienne valeur = 0
Nouvelle valeur = 1
0x0000000000408a4c in __gnu_cxx::new_allocator::construct (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::construct (this=0x1e96208, __p=0x1e96240, __args#0=@0x7fff8ad82260)
at /usr/include/c++/4.3/ext/new_allocator.h:114
#1 0x000000000042169c in std::vector >::push_back (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
La ligne 639 de BPCFGParser.cpp était comme ceci :
PUSH_BEST_PAIR_FOR_TRAVERSAL(i,row,column,grammar->probs[temp_rule.symbol][temp_rule.expansion]);
C'était un macro défini au début du fichier comme ceci :
#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))
Au fait, la classe Traversal est définie comme :
class Traversal { // Classe pour une traversée
public:
Edge *active_edge;
Edge *passive_edge;
Traversal();
Traversal(Edge *a, Edge *p) {active_edge = a; passive_edge = p;}
};
En réalité, je pousse quelque chose dans le vecteur n_best_pairs_for_traversals, qui est un membre d'une instance de la classe BPCFGParser et le code push_back() écrase d'une manière ou d'une autre sur le vecteur n_best_parses, qui est un membre d'une instance de la classe Edge. Comment cela est-il possible ?