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
Post a Comment