Reputation: 23
I realize it gets kind of long with all the printf
, but I didn't really know how to present my issue better.
I am having problems initializing a struct in c properly. I have tried debugging with printf
to show my issue. Essentially I'm creating a list of structs, using the following function:
Vertex *Vertex_new(int n){
Vertex *vert = malloc(sizeof(Vertex));
if(!vert){return NULL;}
vert->id = n;
vert->outNeighbours = malloc(sizeof(LinkedList));
vert->outNeighbours = LinkedList_new();
vert->inNeighbours = malloc(sizeof(LinkedList));
vert->inNeighbours = LinkedList_new();
return vert;
}
struct Vertex {
int id; // a number in [0; numVertices[
LinkedList *outNeighbours; // A linked list of vertices.
LinkedList *inNeighbours; // A linked list of vertices
};
And that is used for the creation of the following struct, with function right after. The function after, called Graph_new()
, I have an issue with saving the Vertex
, properly inside the list. I don't know which part I'm doing wrong, but I'm assuming it's something to do with how I'm initializing the list, and as such made a bunch of print statements to try and understand the problem:
struct Graph {
int numVertices;
int numEdges;
Vertex *vertices; // An array of numVertices vertices
};
Graph *Graph_new(int n){
Graph *grf = malloc(sizeof(Graph));
if(!grf){return NULL;}
grf->numEdges = 0;
grf->numVertices = n;
Vertex list[n];
grf->vertices = malloc(sizeof(Vertex*)*n);
for(int i = 0; i < n;i++){
list[i] = *Vertex_new(i);
}
grf->vertices = list;
// My attempt at debugging, `grf` is simply returned after these print statements:
printf("Inside graph_new for list:\n");
printf("%d ",list[0].id);
printf("%d ",list[1].id);
printf("%d ",list[2].id);
printf("%d ",list[3].id);
printf("%d \n",list[4].id);
// Det her virker herinde, men ikke uden for
// er der et problem i hvordan jeg gemmer listen?
printf("Inside graph_new for grf->vertices:\n");
printf("%d ",grf->vertices[0].id);
printf("%d ",grf->vertices[1].id);
printf("%d ",grf->vertices[2].id);
printf("%d ",grf->vertices[3].id);
printf("%d \n",grf->vertices[4].id);
printf("%d ",grf->vertices[0].id);
printf("%d ",grf->vertices[1].id);
printf("%d ",grf->vertices[2].id);
printf("%d ",grf->vertices[3].id);
printf("%d \n",grf->vertices[4].id);
return grf;
}
In another function, I call graph_new(n)
. n
is here read from a file, n
in this case is 5, which I have tested, to make sure it reads it correctly, so it's a guaranteed 5.
I tested two way of printing, in order to understand what is happening. The first:
Graph *newG = Graph_new(n);
// outside of graph_new:
printf("outside of graph_new, newG->vertices:\n");
printf("%d ",newG->vertices[0].id);
printf("%d ",newG->vertices[1].id);
printf("%d ",newG->vertices[2].id);
printf("%d ",newG->vertices[3].id);
printf("%d \n",newG->vertices[4].id);
printf("%d ",newG->vertices[0].id);
printf("%d ",newG->vertices[1].id);
printf("%d ",newG->vertices[2].id);
printf("%d ",newG->vertices[3].id);
printf("%d \n",newG->vertices[4].id);
Gives the output:
Inside graph_new for list:
0 1 2 3 4
Inside graph_new for grf->vertices:
0 1 2 3 4
0 1 2 3 4
outside of graph_new, newG->vertices:
0 -285208794 -603392624 -603392624 0
0 -285208794 -603392624 -603392624 0
So at first I assumed it was because the list was not saved properly, or the vertices was not saved properly inside the list.
But if I then print this outside of Graph_new
:
Vertex vert1 = newG->vertices[0];
Vertex vert2 = newG->vertices[1];
Vertex vert3 = newG->vertices[2];
Vertex vert4 = newG->vertices[3];
Vertex vert5 = newG->vertices[4];
printf("works outside:\n");
printf("%d ", vert1.id);
printf("%d ", vert2.id);
printf("%d ", vert3.id);
printf("%d ", vert4.id);
printf("%d \n", vert5.id);
// Saving the vertices back in the array works
newG->vertices[0] = vert1;
newG->vertices[1] = vert2;
newG->vertices[2] = vert3;
newG->vertices[3] = vert4;
newG->vertices[4] = vert5;
Vertex vert11 = newG->vertices[0];
Vertex vert22 = newG->vertices[1];
Vertex vert33 = newG->vertices[2];
Vertex vert44 = newG->vertices[3];
Vertex vert55 = newG->vertices[4];
printf("Works again\n");
printf("%d ", vert11.id);
printf("%d ", vert22.id);
printf("%d ", vert33.id);
printf("%d ", vert44.id);
printf("%d \n", vert55.id);
// ------------------------------
printf("Doesn't work: \n");
Vertex vvert1 = newG->vertices[0];
Vertex vvert2 = newG->vertices[1];
Vertex vvert3 = newG->vertices[2];
Vertex vvert4 = newG->vertices[3];
Vertex vvert5 = newG->vertices[4];
printf("%d ", vvert1.id);
printf("%d ", vvert2.id);
printf("%d ", vvert3.id);
printf("%d ", vvert4.id);
printf("%d \n", vvert5.id);
I get the following output:
Inside graph_new for list:
0 1 2 3 4
Inside graph_new for grf->vertices:
0 1 2 3 4
0 1 2 3 4
works outside:
0 1 2 3 4
Works again
0 1 2 3 4
Doesn't work:
0 -2035597530 519880720 -2031896736 -1398417392
If anyone is has the time to understand it and give a helping hand, I'd REALLY appreciate it. I might not make it in time for the exam, but at least I'd know what I did wrong.
Upvotes: 2
Views: 59
Reputation: 12732
Graph *Graph_new(int n){
…
Vertex list[n];
grf->vertices = malloc(sizeof(Vertex*)*n);
for(int i = 0; i < n;i++){
list[i] = *Vertex_new(i);
}
grf->vertices = list;
…
return grf;
}
list
array is local to Graph_new
function and will be destroyed once control exits the function, thus you cannot take reference of list
out of Graph_new
it is undefined behavior.
Also *Vertex_new(i);
has memory leaks, as you are loosing reference to the allocation.
Upvotes: 3