当前位置:  开发笔记 > 编程语言 > 正文

C++ vector push_back()会覆盖另一个相同类型的向量?

如何解决《C++vectorpush_back()会覆盖另一个相同类型的向量?》经验,为你挑选了1个好方法。

我用这种方式定义了一个名为nth_best_parse的类:

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

然后我将这个nth_best_parse的向量声明为两个不同类的成员:

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

        

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

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

    };



class BPCFGParser {

  public:

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

//    vector > nth_best_pairs;
    vector > n_best_pairs_for_traversals;

    

    void compute_n_best_parses(Edge *e, int n);

    
}

然后我用gdb运行这个程序(顺便说一句,我使用Linux Ubuntu 9.04,g ++ 4.3.3,GNU gdb 6.8-debian)并在一些条件下(在一些条件下)在compute_n_best_parses()定义的末尾设置一个断点.找到我想要的这个函数的确切调用,我正在从分段错误中追溯).当gdb命中断点时,我发出了一组命令,gdb输出如下:

(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

Old value = 0
New value = 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

BPCFGParser.cpp的639行是这样的:

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

这是在文件开头定义的宏:

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

顺便说一句,Traversal类被定义为:

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

所以实际上我正在向向量n_best_pairs_for_traversals推送一些东西,它是BPCFGParser类的一个实例的成员,push_back()代码以某种方式覆盖了向量n_best_parses,它是Edge类实例的成员.这怎么可能呢?



1> Martin York..:

你显然在某处存在内存损坏问题.
但是这里没有足够的信息来帮助你.

但是你正在编写C++代码,你的类包含指针.
这不是一个好兆头(在C++类中几乎不应该有RAW指针).
对于没有经验的C++开发人员来说,这通常也是导致内存损坏的原因!

你遵守了4的规则吗?

确保包含RAW拥有指针的每个类:

constructor

复制构造函数

赋值运算符

析构函数.

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有