【问题标题】:Memory Leak in suffix tree c++后缀树c ++中的内存泄漏
【发布时间】:2014-03-01 05:22:42
【问题描述】:

我使用了来自source 的库streed2006.cpp。该代码在删除边缘时存在内存泄漏。我使用以下代码从哈希表中清除了边数:

//throwing away the edges from hashtable
for(int t=0;t<HASH_TABLE_SIZE;t++)
{
    Edges[t].Remove();
    Edges[t].start_node == -1

}

valgrind 输出:

3,920 bytes in 245 blocks are definitely lost in loss record 9 of 12
==6301==    at 0x4029F34: operator new(unsigned int) (in /usr/lib/valgrind   /vgpreload_memcheck-x86-linux.so)
==6301==    by 0x804A683: Edge::SplitEdge(Suffix&) (suffix_tree.cpp:555)
==6301==    by 0x804B02F: AddPrefix(Suffix&, int) (suffix_tree.cpp:753)

请指导我如何删除边缘。

能够消除内存泄漏。以下是解决方案:

 void AddPrefix( Suffix &active, int last_char_index )
{
 int parent_node;
 int last_parent_node = -1;

for ( ; ; ) {
    Edge edge;
    parent_node = active.origin_node;
    if ( active.Explicit() ) {
        edge = Edge::Find( active.origin_node, T[ last_char_index ] );
        if ( edge.start_node != -1 )
            break;
    } else { //implicit node, a little more complicated
        edge = Edge::Find( active.origin_node, T[ active.first_char_index ] );
        int span = active.last_char_index - active.first_char_index;
        if ( T[ edge.first_char_index + span + 1 ] == T[ last_char_index ] )
            break;
        parent_node = edge.SplitEdge( active );
    }

    Edge *new_edge = new Edge( last_char_index, T.N, parent_node );
    new_edge->Insert();
    //cout << "Created edge to new leaf: " << *new_edge << "\n";
    AddSuffixLink( last_parent_node, parent_node );
    if ( active.origin_node == 0 ) {
        //cout << "Can't follow suffix link, I'm at the root\n";
        active.first_char_index++;
    } else {
    /*
        cout << "Following suffix link from node "
             << active.origin_node
             << " to node "
             << Suffix_Nodes[ active.origin_node ].suffix_node
             << ".\n";
    */
        active.origin_node = Suffix_Nodes[ active.origin_node ].suffix_node;
        //cout << "New prefix : " << active << "\n";
    }
    active.Canonize();
delete(new_edge);
new_edge = NULL;
}
AddSuffixLink( last_parent_node, parent_node );
active.last_char_index++;  //Now the endpoint is the next active point
active.Canonize();
};

int Edge::SplitEdge( Suffix &s )
{
//cout << "Splitting edge: " << *this << "\n";
Remove();
Edge *new_edge =
  new Edge( first_char_index,
            first_char_index + s.last_char_index - s.first_char_index,
            s.origin_node );
new_edge->Insert();
Suffix_Nodes[ new_edge->end_node ].suffix_node = s.origin_node;
first_char_index += s.last_char_index - s.first_char_index + 1;
start_node = new_edge->end_node;
Insert();
//cout << "New edge: " << *new_edge << "\n";
//cout << "Old edge: " << *this << "\n";
delete(new_edge);
//return new_edge->end_node;
return(start_node);
}

【问题讨论】:

  • 具体问题是?
  • @leonardo 程序内存泄漏。我的分析表明这是由于边缘没有被删除。所以我需要有人告诉我如何在不再需要边缘时删除它们。
  • 你读过Edges::Remove()函数上方的评论区吗?
  • @Leonardo 是的,我做到了,它不会删除边缘,只是将其从哈希表中删除。我需要做的。我怀疑我需要修改 `dump_edges()` 来删除边。但不知道怎么做?
  • 是的,这段代码中肯定没有delete,但是实现了new动态分配。所以,我认为你是对的。解决方案是为每个使用的new 实现一个delete

标签: c++ memory memory-management memory-leaks valgrind


【解决方案1】:
 void AddPrefix( Suffix &active, int last_char_index )
{
 int parent_node;
 int last_parent_node = -1;

for ( ; ; ) {
    Edge edge;
    parent_node = active.origin_node;
    if ( active.Explicit() ) {
        edge = Edge::Find( active.origin_node, T[ last_char_index ] );
        if ( edge.start_node != -1 )
            break;
    } else { //implicit node, a little more complicated
        edge = Edge::Find( active.origin_node, T[ active.first_char_index ] );
        int span = active.last_char_index - active.first_char_index;
        if ( T[ edge.first_char_index + span + 1 ] == T[ last_char_index ] )
            break;
        parent_node = edge.SplitEdge( active );
    }

    Edge *new_edge = new Edge( last_char_index, T.N, parent_node );
    new_edge->Insert();
    //cout << "Created edge to new leaf: " << *new_edge << "\n";
    AddSuffixLink( last_parent_node, parent_node );
    if ( active.origin_node == 0 ) {
        //cout << "Can't follow suffix link, I'm at the root\n";
        active.first_char_index++;
    } else {
    /*
        cout << "Following suffix link from node "
             << active.origin_node
             << " to node "
             << Suffix_Nodes[ active.origin_node ].suffix_node
             << ".\n";
    */
        active.origin_node = Suffix_Nodes[ active.origin_node ].suffix_node;
        //cout << "New prefix : " << active << "\n";
    }
    active.Canonize();
//ADDED THIS DELETE HERE
delete(new_edge);
new_edge = NULL;
}
AddSuffixLink( last_parent_node, parent_node );
active.last_char_index++;  //Now the endpoint is the next active point
active.Canonize();
};

int Edge::SplitEdge( Suffix &s )
{
//cout << "Splitting edge: " << *this << "\n";
Remove();
Edge *new_edge =
  new Edge( first_char_index,
            first_char_index + s.last_char_index - s.first_char_index,
            s.origin_node );
new_edge->Insert();
Suffix_Nodes[ new_edge->end_node ].suffix_node = s.origin_node;
first_char_index += s.last_char_index - s.first_char_index + 1;
start_node = new_edge->end_node;
Insert();
//cout << "New edge: " << *new_edge << "\n";
//cout << "Old edge: " << *this << "\n";
//ADDED THIS DELETE HERE
delete(new_edge);
//return new_edge->end_node;
return(start_node);
}

【讨论】:

    猜你喜欢
    • 2010-12-20
    • 2010-10-11
    • 1970-01-01
    • 2016-01-27
    • 2010-11-11
    • 2017-02-18
    • 1970-01-01
    • 2010-09-18
    • 2021-11-28
    相关资源
    最近更新 更多