Reputation:
I need some help here and I couldn't find anything relevant by searching.
So I am writing a C program and something weird is going on. My program crashes when I run it normally but when I debug it, it works fine. I don't get what's going on.
It's an assignment and it's due on Wednesday so I am freaking out a little.
(I am using the CodeBlocks IDE, if that's any help.)
EDIT: Sorry about not posting this from the beginning, I thought the problem might have been me using the debugger wrong or having to change debugger settings (if that's even possible). Here is the function that seams to be causing the problems:
double **makeMatrix(struct graph *head, char **nodes)
{
double **tmpMatrix=NULL;
int i=0, j=0;
struct graph *tmp=NULL;
if(nodes==NULL || head==NULL)
return NULL;
for(i=0; nodes[i] != NULL; i++);
tmpMatrix=calloc(i+1, sizeof(double*));
if(NULL==tmpMatrix)
{
printf("No Memory!");
return NULL;
}
for(j=0; j<i; j++)
{
tmpMatrix[j]=calloc(i+1, sizeof(double*));
if(NULL==tmpMatrix[j])
{
printf("No Memory!");
return NULL;
}
tmpMatrix[j][i] = -INF;
}
for(i=0; tmpMatrix[i] != NULL; i++)
{
for(j=0; tmpMatrix[i][j] != -INF; j++)
{
tmpMatrix[i][j] = INF;
}
}
for(tmp=head; tmp->fromNode >=0; tmp= tmp->next)
{
tmpMatrix[tmp->fromNode][tmp->toNode] = tmp->length;
printf("%f\n", tmpMatrix[tmp->fromNode][tmp->toNode] );
}
return tmpMatrix;
}
The assignment is about writing a program that is able to read nodes and graphs to calculate the shortes path. Where were given the Dijkstra algorithm to solve this problem. That's why we have to create an matrix we stores the length of the edges.
Also, with the debugger I was executing it step by step.
Upvotes: 0
Views: 121
Reputation: 6204
I see a few problems or potential issues depending on all the code and input you haven't shown:
The line:
tmpMatrix[j]=calloc(i+1, sizeof(double*));
should be:
tmpMatrix[j]=calloc(i+1, sizeof(double));
If sizeof(double*) == 8
you might be ok by chance but better to be actually correct
In the first for
loop you seem to be counting the size of the nodes
array. I don't understand the use of nodes in this case since it isn't used elsewhere in the function. A better function signature would be to pass the size of the array needed. Make sure that nodes
is properly NULL
terminated or you'll run into issues. I would also add another variable to make the array size explicit since you reuse i
later on, something like:
int arraySize = 0;
...
for (i = 0; nodes[i] != NULL; ++i);
arraySize = i;
tmpMatrix = calloc(arraySize + 1, sizeof(double*));
For setting values of tmpMatrix
to INF
it would be better to use explicit array indexes, like:
for (i = 0; i < arraySize; ++i)
{
for (j = 0; j < arraySize; ++j)
{
tmpMatrix[i][j] = INF;
}
}
This makes it much clearer what you are doing and less error prone.
You should explicitly check for a NULL
pointer in your last loop:
for (tmp = head; tmp->fromNode >= 0; tmp = tmp->next)
If the linked list is not setup correctly then tmp
may become NULL
and you'll dereference it causing undefined behaviour. Simply add a check to the loop like:
for (tmp = head; tmp != NULL && tmp->fromNode >= 0; tmp = tmp->next)
You should check for valid array indexes for tmpMatrix
inside your last loop:
tmpMatrix[tmp->fromNode][tmp->toNode] = tmp->length;
if tmp->fromNode
or tmp->toNode
are invalid array indexes you'll overflow/underflow the array and cause UB. Even if you "know" these values should be correct it is far safer to add a check just in case:
if (tmp->fromNode >= 0 && tmp->fromNode < arraySize &&
tmp->toNode >= 0 && tmp->toNode < arraySize)
{
...
}
A lot of these points are in the "defensive programming" category. Yes, nodes
and head
should be NULL terminated and have correct indices, but maybe there's another bug somewhere and they're not, or invalid input was received, or a stray cosmic ray flipped a bit in a memory cell. By checking your inputs a bit more carefully you can prevent UB from occurring and randomly crashing on you like you've experienced.
Upvotes: 1