Je suis en train d'écrire un programme qui traite des lots de mises à jour dans un graphe au sein de nouveaux nœuds et arêtes. J'ai récemment intégré un schéma de fenêtre glissante qui vérifie si les bords déjà dans le graphique sont dans la fenêtre, et sinon les supprime. J'utilise un bord et la classe Node comme suit:Récupération d'une erreur de segmentation dans un programme de traitement de flux de données
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);
}
};
En utilisant un ensemble de données que je reçois une erreur de segmentation après traitement 69 fichiers batch avec une taille de fenêtre coulissante de 5 tout en essayant d'accéder à un bord à l'aide d'un itérateur de bord. En utilisant un autre ensemble de données, je reçois une erreur de segmentation après 69 fichiers batch en essayant de supprimer un pointeur Edge non vide dans la liste d'adjacence (essayant de libérer la mémoire). Je suis à bout de nerfs en essayant de comprendre ce qui ne va pas. La version de fenêtre non-glissante de ce programme fonctionne très bien. Je sais aussi que l'utilisation d'une structure de données STL Deque serait préférable pour les fenêtres coulissantes. Cependant, je travaille avec un code assez volumineux, et j'aimerais pouvoir le résoudre sans avoir à utiliser une deque. Merci d'avance. Edit: Il arrive sur deux lignes différentes:
for (int i = 0; i < node_list.size(); i++)
{
vector<Edge *>::iterator adj_it;
for (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;
}
}
}
Il arrive sur la ligne:
if ((max_batch_num - (*adj_it)->timestamp) > time_window)
sur l'utilisation du premier ensemble de données. Le problème ici est que même si le vecteur n'est pas vide, les pointeurs du vecteur pointent vers une mémoire qui ne fait pas partie de l'application. Quand j'utilise gdb pour tenter d'imprimer:
print (*adj_it)->timestamp
donne: Tentative de prendre l'adresse de la valeur dans la mémoire non
Cela ne devrait pas se produire si que les bords sont ajoutés à la liste de contiguïté. Et sur l'utilisation du second ensemble de données l'erreur se produit lors de l'utilisation:
delete (*adj_it);
où adj_it est un itérateur pour le vecteur de adjacency_list. Ce qui est aussi bizarre, c'est que si j'augmente la fenêtre glissante en disant 'n', le même problème se produit après 'n' lots.
Ajout de la fonction deleteEdge:
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 to delete an Edge pointer which is NULL"<<endl;
exit(1);
}
return e_it;
}
Aussi je l'ai déjà utilisé que des index, et je l'ai essayé à nouveau après la réponse de @Julius. C'est ma nouvelle boucle de suppression.
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++;
}
}
Cependant, je reçois les mêmes erreurs malgré tout.
BTW. J'apprécie vraiment tous les commentaires jusqu'à présent. Merci pour votre temps. Editer: La mémoire trouvée fuit dans une partie différente du code en utilisant valgrind. Se débarrasser de ce code (ce n'était pas vraiment nécessaire à l'algorithme) s'en est débarrassé. J'accepte la réponse de @Julius car cela aurait résolu le problème selon ma déclaration d'origine. Merci également à @RetiredNinja, @Beta et @Golazo pour leurs excellents commentaires.
Quelle ligne cela arrive-t-il? –
Si vous avez des problèmes de mémoire, la première chose à faire est de se débarrasser des pointeurs propriétaires –
Il est temps d'exécuter votre débogueur. –