Alessandro
Alessandro

Reputation: 4110

Cannot access index of array pointer C

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;

Upvotes: 0

Views: 282

Answers (3)

Nuf
Nuf

Reputation: 31

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.

Upvotes: 1

t0mm13b
t0mm13b

Reputation: 34592

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.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726929

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++) {
}

Upvotes: 2

Related Questions