0

I am trying to set up an adjacent list array in C:

mygraph->table = (Node *)malloc(MaxSize * sizeof(Node));
check(mygraph->table, error);
int i;
for(i = 1; i <= MaxSize; i++)
{
    mygraph->table[i].name = NULL;
    mygraph->table[i].outlist = NULL;
    mygraph->table[i].outdegree = 0;
}
...

When I run this code, it works fine. But when I try to access an index in the table I get a segmentation fault:

mygraph->table[n].name = name;

I checked the n index, and it is correct. MaxSize is 10, but I get a segmentation fault even when n = 1.

EDIT:

typedef struct linkedlist { // linked list of ints (for use in Node)
  int index;
  struct linkedlist *next;
} List;

typedef struct { // a Node of a Graph
  char *name;
  List *outlist; // adjacency list
  int outdegree; // length of outlist
  //double pagerank_score; //not needed for this exercise
} Node;

typedef struct {
  // your code goes here
  int MaxSize;      /*Maximum number of vertices that the graph can constain*/
  Node *table;     /*Adjacency lists' array*/
} Graph;
1
  • 1
    did you allocate memory for name? Commented Apr 17, 2016 at 11:42

3 Answers 3

2

I get a segmentation fault even when n = 1.

This is because your code has undefined behavior. It writes past the end of the array:

for(i = 1; i <= MaxSize; i++) // should be i=0 ; i<MaxSize

When n is 10 the code does not crash on your system - perhaps because malloc adds enough padding at the end of the block to accommodate an extra element past the end of the array, but the error is still there.

You can find such hidden errors using a memory profiler, e.g. valgrind.

The fix is to use correct indexes in the initialization:

for(int i = 0 ; i != MaxSize ; i++) {
}
Sign up to request clarification or add additional context in comments.

8 Comments

It crashes for every number, even 10
I tried your fix but it still crashes... I'll post the declaration of Node and Graph
@Alessandro It's probably crashes in some other place now, because this is the error in the code that you have posted.
There's not much I do really, just initialise and try to change one index.
@Alessandro You may want to post the "try to change one index" code, too.
|
1

This is the key:

mygraph->table[n].name = name;

There is no mention of allocating memory for the name variable.

Also, assigning name variable on the right hand side of expression, it would be better to indicate, by using strncpy or strdup to state your intention.

The onus is on you to ensure you do indeed, free the memory occupied by the name member also.

3 Comments

If the name variable on the right was allocated properly, the assignment should be valid, but indeed, if the original pointer gets deallocated somewhere else later, then there is a problem.
Indeed, it is valid, but to the discerning eye, what is name, where did it come from? Cue looking around elsewhere, it would be easier if it had the intention of indicating that it was strcpy or strdup , which clues in more in 'a-ha, its a pointer variable'. :)
I tried using strcpy(mygraph->table[n].name, name); but it still fails
1

Your loop need to run from 0 to MaxSize-1, like this:

for(i = 0; i < MaxSize; i++)
{
    mygraph->table[i].name = NULL;
    mygraph->table[i].outlist = NULL;
    mygraph->table[i].outdegree = 0;
}

so the first element will be at mygraph->table[0] and the last element will be at
mygraph->table[MaxSize-1].

In pointer arithmetic, the first element will start at mygraph->table and the last element will start at:

((mygraph->table) + MaxSize-1) 

and would end at:

((mygraph->table) + MaxSize) 

table[MaxSize] is equivalent *((mygraph->table) + MaxSize) and this is out of the array boundaries.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.