While implementing a Dijkstra-Search on a Graph, I call a seperate method to perform the search, handing it a pointer to my nodes and direct values for start/endpoint and array size. Notably,t he method doesn't change anything about the node array, it only reads values.
When I try to free the node array after, it causes a SIGSEGV
int djkstra(int start, int goal, node* v, int n){
//Algorithm logic
return result;
}
int main(){ [...]
node* v = (node*)malloc(sizeof(node)*(n+1));
djkstra(start, goal, v, n);
free(v); //This throws a SIGSEGV
return 0;}
I can't find anything online about why this might cause things to break. I tried adding a seperate array declared in main as well (which gets changed in the method), which I also couldn't free after.
Is this some kind of obscure C++ rule? I couldn't find anything online about this, and the method should be long resolved when I call free(v).
I'll put a working example here for clarification, though note there is another strange free() segfault in djkstra which I'll probably need to make another question for later.
#include <iostream>
#include <stdio.h>
class node{
public: int edges;
public: int* pre;
public: int* cost;
public: void addpre(int i, int c){/*Insertion logic*/}
public: void destroy(){/*Frees the arrays*/}
};
int djkstra(int start, int goal, node* v, int n){
bool* visited =(bool*)malloc(sizeof(bool)*n+1);
int* costss = (int*)malloc(sizeof(int)*n+1);
for(int i=0; i<=n; i++){
costss[i]=5000001;
visited[i]=false;
}
bool allvisit=false;
costss[start]=0;
while(true){
int smallest=5000000;
int cur=0;
for(int i=1; i<=n; i++){
if(!visited[i] && costss[i]<smallest){
smallest=costss[i];
cur=i;
}
}
if(cur==0){allvisit=true; break;}
if(cur==goal){break;}
visited[cur]=true;
for(int j=0; j<v[cur].edges; j++){
int jcost=v[cur].cost[j]+smallest;
if(jcost<costss[v[cur].pre[j]]){
costss[v[cur].pre[j]]=jcost;
}
}
}
int res;
if(allvisit){res=5000000;}
else{res=costss[goal];}
free(visited);
free(costss); //Freeing this causes SIGSEGV
return res;
};
int main() {
int n=2; //number of nodes
int s=2; //number of waypoints
node* v = (node*)malloc(sizeof(node)*(n+1));
int* costs = (int*)malloc(sizeof(int)*s); //Saving cost of waypoints
int* market = (int*)malloc(sizeof(int)*s); //Saving location of waypoints
//Example case
int start=1;
int goal=2;
v[1].edges=1;
v[2].edges=1;
v[1].pre=(int*)malloc(sizeof(int));
v[1].pre[0]=2;
v[2].pre=(int*)malloc(sizeof(int));
v[2].pre[0]=1;
v[1].cost=(int*)malloc(sizeof(int));
v[2].cost=(int*)malloc(sizeof(int));
v[2].cost[0]=30;
v[1].cost[0]=30;
costs[0]=15;
costs[1]=20;
market[0]=1;
market[1]=2;
int mincost=5000000;
for(int i=0; i<s; i++){
int j=djkstra(start, market[i], v, n);
costs[i]=costs[i]+j;
}
for(int i=0; i<s; i++){
costs[i]=costs[i]+djkstra(market[i], goal, v, n);
if(costs[i]<mincost){mincost=costs[i];}
}
if(mincost==5000000){printf("impossible\n");}
else{
int hours=mincost/60;
int minutes=mincost-(hours*60);
if(minutes<10){printf("%d:0%d\n", hours, minutes);}
else{printf("%d:%d\n", hours, minutes);}
}
for(int i=1; i<=n; i++){
v[i].destroy();
}
free(market); //Freeing this works fine
free(costs); //Freeing this works fine
free(v); //Freeing this causes SIGSEGV
return 0;
}
bool* visited =(bool*)malloc(sizeof(bool)*n+1);is not the same asbool* visited =(bool*)malloc(sizeof(bool)*(n+1));I haven't looked further, but the program likely exhibits undefined behavior by way of a buffer overrun, and corrupts the heap.class nodeis used as a C struct.malloc/freestuff withnew/deleteor standard library constructs likestd::vector. Even if you can find out what goes wrong here this time, such memory-related error will show up again and again due to the bad coding habits.malloc) you should take that as a sign that you're likely are doing something wrong.