-
Core Dump in While()
Hey, I'm using the following code:
Code:
do {
printf("Start scan\n");
fscanf(in, "%d%d", &a, &b);
printf("scanned %d %d\n", a, b);
if(a !=0 && b!= 0) addDirectedEdge(G, a, b);
printf("return\n");
} while(a != 0 || b != 0);
printf("done");
and I'm getting a core dump immediately after it prints 'return' when it reads in '0 0' from any line in the input. I tried using a counter to have a set number of iterations and it still core dumped when the while loop went false. a and b are ints. Anyone know why this might be happening? Any help would be appreciated.
-
Well for starters, you get rid of everything that we can't actually test, which will likely tell you where your problem is. Let's see if I'm right:
Code:
#include <stdio.h>
int main( void )
{
int a, b;
do
{
printf("Enter a b: ");
fflush( stdout );
if( scanf("%d%d", &a, &b ) != 2 ) /* Make sure they follow directions. */
{
printf("I said, enter a b.\n"); /* Yell at them. */
while( (a = getchar()) != '\n' ); /* Clean their mess. */
continue;
}
printf("scanned %d %d\n", a, b );
if( a != 0 && b != 0 )
printf("yay, no zeros!\n");
printf("return\n");
}
while( a != 0 || b != 0 );
printf("done\n");
return 0;
}
Quzah.
-
rest of code
Thanks for looking at it. Sorry, I posted in kindof a hurry and didn't really put enough to solve the problem. Also, input format does not need to be checked, just the values themselves. Also, also, when I comment out the call to addDirectedEdge it still crashes.
The program is designed to build a directed graph representation then find the strongly connected components (it builds lists of which nodes each node can get to, and searches through them to find which ones are part of a cycle) Here's the whole file:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "List.h"
#include "Graph.h"
int main(int argc, char **argv) {
ListHndl S;
GraphHndl G, GT;
FILE *in, *out;
int n, a, b, i, rents;
if(argc != 3) {
printf("Usage: %s input output", argv[0]);
exit(1);
}
in = fopen(argv[1], "r");
out = fopen(argv[2], "w");
if( in==NULL ){
printf("Unable to open file %s for reading\n", argv[1]);
exit(1);
}
if( out==NULL ){
printf("Unable to open file %s for writing\n", argv[2]);
exit(1);
}
/*build the graph*/
fscanf(in, "%d", &n);
G = NewGraph(n);
printGraph(G,stdout);
do {
printf("Start scan\n");
fscanf(in, "%d%d", &a, &b);
printf("scanned %d %d\n", a, b);
if(a!=0 && b!= 0) addDirectedEdge(G, a, b);
printf("return\n");
} while(a != 0 || b != 0);
printf("done");
for(i = 1; i<= getOrder(G); i++) {
printf("Build List");
insertAfterLast(S, i);
}
/*Run DFS*/
DFS(G, S);
GT = Transpose(G);
DFS(GT, S);
rents = 0;
for(i = 1; i<= getOrder(GT); i++) {
if(getParent(GT, i) == NULL) rents++;
}
fprintf(out, "Adjacency list representation of G:\n");
printGraph(G, out);
fprintf(out, "\n");
fprintf(out, "G contains %d strongly connected components:", rents);
moveFirst(S);
while(!offEnd(S)) {
if(getParent(GT, getCurrent(S)) == NULL)
fprintf(out, "\n%d", getCurrent(S));
else fprintf(out, " %d", getCurrent(S));
moveNext(S);
}
return 0;
}
List and Graph are implimentations we had to write for graph building. When I run my program in bcheck it gives me the error:
"signal SEGV (no mapping at the fault address) in insertAfterLast at 0x1239c
0x0001239c: insertAfterLast+0x0028: ba,a insertAfterLast+0x14410"
the function insertAfterLast is called in addDirectedEdge and uses the following code:
Code:
void addDirectedEdge(GraphHndl G, int u, int v) { /* Pre: 1<=u<=n, 1<=v<=n */
if(1 <= u && u <= getOrder(G) && 1 <= v && v <= getOrder(G)) {
insertAfterLast(G->near[u], v);
G->edges++;
printf("Edge added\n");
}
}
-------------------------------------------------------------------
void insertAfterLast(ListHndl L, ListItem data) {
ListNodeHndl newn = NewNode(data);
newn->prev = L->last;
if(L->last != NULL) L->last->next = newn;
else L->first = newn;
L->last = newn;
L->length += 1;
}
The structs being dealt with are as follows:
Code:
typedef struct Graph *GraphHndl;
struct Graph {
int n;
int edges;
char **color;
ListHndl *near;
int *parent;
int *disc;
int *fin;
};
---------------------------------------------
typedef struct ListNode *ListNodeHndl;
struct ListNode {
ListItem item;
ListNodeHndl prev;
ListNodeHndl next;
};
struct List {
int length;
ListNodeHndl first;
ListNodeHndl last;
ListNodeHndl curr;
};
the List implimentation was used in a previous program and as far as I know works w/o any problems.
and some constructors, too:
Code:
GraphHndl NewGraph(int n) {
int i;
printf("New Graph %d\n", n);
GraphHndl G = malloc(sizeof(struct Graph));
G->n = n;
G->edges = 0;
G->color = (char**)malloc(sizeof(char)*5*(n+1));
G->near = (ListHndl*)malloc((n+1)*sizeof(ListHndl));
G->parent = (int*)malloc(sizeof(int) * (n+1));
G->disc = (int*)malloc(sizeof(int) * (n+1));
G->fin = (int*)malloc(sizeof(int) * (n+1));
for(i = 1; i <= n; i++) {
G->color[i] = "white";
G->near[i] = New_List();
G->parent[i] = NULL;
G->disc[i] = NULL;
G->fin[i] = NULL;
}
printf("Graph done\n");
return G;
}
----------------------------------------------------------------------
ListHndl New_List(void){
ListHndl new = malloc(sizeof (struct List));
new->length = 0;
new->first = NULL;
new->last = NULL;
new->curr = NULL;
return new;
}
-
Code:
GraphHndl NewGraph(int n) {
int i;
printf("New Graph %d\n", n);
GraphHndl G = malloc(sizeof(struct Graph));
G->n = n;
G->edges = 0;
G->color = (char**)malloc(sizeof(char)*5*(n+1));
G->near = (ListHndl*)malloc((n+1)*sizeof(ListHndl));
G->parent = (int*)malloc(sizeof(int) * (n+1));
G->disc = (int*)malloc(sizeof(int) * (n+1));
G->fin = (int*)malloc(sizeof(int) * (n+1));
for(i = 1; i <= n; i++) {
G->color[i] = "white";
G->near[i] = New_List();
G->parent[i] = NULL;
G->disc[i] = NULL;
G->fin[i] = NULL;
}
printf("Graph done\n");
return G;
}
First problem - remove all those casts. You didn't cast the first one, so why bother with the others.
Second problem - you're not allocating enough memory (or too much).
> G->color = (char**)malloc(sizeof(char)*5*(n+1));
Where did that 5 come from? My guess is you started with just sizeof(char) (which is wrong) and found it crashed. Through experiment, you found a fudge of 5 fixed the problem.
You should have
G->color = malloc(sizeof(char*)*(n+1));
color is a char**, so what you want is a number (n+1) of char*
In it's most general form, p = malloc( n * sizeof *p ); always does the right thing no matter what type p is to start with.
> "signal SEGV (no mapping at the fault address) in insertAfterLast at 0x1239c
Run the program inside the debugger. When it segfaults, you can then examine all your variables to determine what went wrong.
> the List implimentation was used in a previous program and as far as I know works w/o any problems.
Re-use is good, but just because it appeared to work doesn't make it bug-free.
-
The casts were to help me keep track of the sizes of everything and b/c I wasn't sure if it would partition the space into correctly sized arrays w/o a cast or not.
The *5 is b/c the color was always a 5 letter word. Though looking at it again since it's just an array of pointers I don't need to malloc that much space. [fixed].
With further testing, the List implimentation works fine under all similary circumstances. While it was made for a previous assignment it was designed for use in this one and later assignments as well.
Anyway, the problem ended up dissapearing for no apparant reason. I think it was b/c I went to a friend's house and had him look at it and having two CMPE majors in the same place convinced it to work. After that, another hour of debugging got the program up and running as it should.
Thanks for the suggestions and reading over my code.
-
> The *5 is b/c the color was always a 5 letter word.
In which case, you're doubly wrong.
You're allocating an array of pointers, not an array of chars.
Besides, "white" takes up 6 bytes in memory (you forgot to count the \0 at the end)
char *foo = "this is a really long sentence, but the size of the pointer is still 4 bytes";
Pointers are independent of the amout of memory they point to.