c++ - Geting a segfault on in a data stream processing program -


i writing program processes batches of updates graph in of new nodes , edges. incorporated sliding window scheme checks see if edges in graph in window, , if not deletes them. using edge , node class follows:

class edge { public:  uint64_t source;  uint64_t target;  unsigned type;  std::string label;  uint64_t timestamp;  bool directed;  bool extracted;  edge(){}  edge(edge *e);  edge(uint64_t, uint64_t, unsigned, std::string, time_t, bool);  bool operator ==(const edge *other)   {   return((this->source==other->source)&&(this->target==other->target)&& \           (this->type==other->type));   } };     class node {   public:   uint64_t id;   unsigned type;   std::string label;   uint64_t timestamp;   std::vector<edge *> adjacent_edges;   node(){}   node(node *);   bool push_edge(edge *e)   {     try     {      adjacent_edges.push_back(e);     }     catch(std::bad_alloc&)     {      std::cout<<"error pushing edge"<<std::endl;      return false;     }     return true;        }     std::vector<edge *>::iterator pop_edge(std::vector<edge *>::iterator e_it)    {     return adjacent_edges.erase(e_it);    }    bool operator ==(const node *other)    {    return (this->id == other->id);    } }; 

on using 1 dataset segfault after processing 69 batch files sliding window size of 5 while trying access edge using edge iterator. on using dataset, segfault after 69 batch files while trying delete non empty edge pointer in adjacency list (trying free memory). @ wit's end trying figure out going wrong. non-sliding window version of program works fine. know using stl deque data structure better sliding windows. however, working pretty large code, , able solve without having use deque. in advance. edit: happens on 2 different lines:

  (int = 0; < node_list.size(); i++)   {   vector<edge *>::iterator adj_it;    (adj_it = (node_list[i])->adjacent_edges.begin(); adj_it != (node_list[i])->adjacent_edges.end(); ++adj_it )   {         if ((max_batch_num - (*adj_it)->timestamp) > time_window)       {             deleteedge(adj_it);           num_edges_deleted++;           --adj_it;        }    }  } 

it happens on line:

if ((max_batch_num - (*adj_it)->timestamp) > time_window) 

on using first dataset. problem here though vector non-empty, pointers in vector pointing memory not part of application. when use gdb attempt print out:

print (*adj_it)->timestamp 

it gives : attempt take address of value not in memory

this shouldn't happen though edges being added adjacency list. , on using second dataset error happens when use:

delete (*adj_it);  

where adj_it iterator adjacency_list vector.

what weird if increase sliding window 'n', same problem happens after 'n' batches.

adding deleteedge function:

vector<fsm::edge *>::iterator fsm::graph::deleteedge(vector<edge *>::iterator e_it) {  //cout<<"deleting edge: e "<<e->source<<" -> "<<e->target<<endl;//debug  fsm::node *s = getnode((*e_it)->source);  fsm::edge *e_tmp = (*e_it);  e_it = s->pop_edge(e_it);  if (e_tmp != null)  {      delete e_tmp;  }  else  {      std::cerr<<"trying delete edge pointer null"<<endl;      exit(1);  }  return e_it; 

}

also used indexes, , tried again after @julius' answer. new deletion loop.

for (int j = 0; j<(node_list[i])->adjacent_edges.size();j++)    {        if ((max_batch_num - ((node_list[i])->adjacent_edges[j])->timestamp) > time_window)                {                                         (node_list[i])->adjacent_edges.erase((node_list[i])->adjacent_edges.begin() + j);                   --j;                   num_edges_deleted++;                }    } 

however, getting same errors regardless.

btw. appreciate comments far. thank time.

edit: found memory leaks in different part of code using valgrind. getting rid of code (it wasn't neccessary algorithm) got rid of it. i'm accepting @julius' answer since have solved problem according original statement. @retiredninja, @beta, , @golazo excellent comments.

for (int = 0; < node_list.size(); i++)   {   vector<edge *>::iterator adj_it;    (adj_it = (node_list[i])->adjacent_edges.begin(); adj_it != (node_list[i])->adjacent_edges.end(); ++adj_it )   {         if ((max_batch_num - (*adj_it)->timestamp) > time_window)       {             deleteedge(adj_it);           num_edges_deleted++;           --adj_it;        }    }  } 

you deleting edge, going backwards --adj_it, iterating on edge deleted deleteedge because loop ++adj_it. try check timestamp object of deleted (invalid) edge object, causing segfault.

either or removing object edge* vector , invalidating iterator.

the important part iterators not indexes. can't erase element , --adj_it. here case using index easier, delete edge object, remove edge pointer vector, continue loop after doing --adj_it do. iterators slower indexes on vectors btw.


Comments

Popular posts from this blog

google chrome - Developer tools - How to inspect the elements which are added momentarily (by JQuery)? -

angularjs - Showing an empty as first option in select tag -

php - Cloud9 cloud IDE and CakePHP -