user1439690
user1439690

Reputation: 679

Correct method to access a structure pointer

I have the following code:

typedef struct AdjMatrix
{
  int nodes;
  int **adjMat;
} graph;

typedef struct Edge
{
  int from,to,weight;
}Edge;


int main(){
  ...

  graph *g=(graph *)malloc(sizeof(graph));
  g-> adjMat = (int **)malloc(sizeof(int *) * vertices);
  for( i = 0; i < vertices; i++){
    g->adjMat[i] = (int *)malloc(sizeof(int) * vertices);
  }
 ...

 Edge *E = (Edge *)malloc(sizeof(Edge) * maxEdges);

 int nEdges = 0;
 for(i = 0; i < g->nodes ; i++){
    for(j= 0; j< g->nodes; j++){
            if(i <= j){
                    printf("%d\t%d\t%d\t\n",i,j,g->adjMat[i][j]);
                    E[nEdges].from = i;
                    E[nEdges].to = j;
                    E[nEdges].weight = g->adjMat[i][j];
                    nEdges++;
            }
            else
                    break;
    }
 }


}

As you can see I am accessing the elements of graph g by "->" and elements of Edge E by ".". I am not understanding why the compiler is throwing an error if I access the elements of graph g by "." or elements of Edge E by "->"? Please explain

Upvotes: 0

Views: 99

Answers (4)

The -> operator is used on a pointer to dereference the pointer and then apply the . operator. So, for example, a->b is the equivalent of (*a).b.

The . operator accesses a member variable as you said. You have noticed that both g and E are pointers, but the reason that the -> operator doesn't work on E is because when you are already using the [] operator on E, which also acts as a dereferencer. For example, the line E[nEdges].to is equivalent to (*(E + nEdges)).to whereas if you tried to use the -> operator in this instance it would be equivalent to (*(*(E + nEdges))).to which would be one dereference too many.

Upvotes: 0

Jeroen Vuurens
Jeroen Vuurens

Reputation: 1251

In your code, both g and e are pointers to structures. An array behaves the same way as a pointer, so e[nEdges] is actually equal to the Edge located at position (e + 12 * nEdges). e[0].from would be the same as e->from.

Upvotes: 0

Cameron Skinner
Cameron Skinner

Reputation: 54306

g is declared as being of type graph*, making it a pointer-to-graph. This means you must access elements of g using the pointer dereference operator: ->.

E is also a pointer, in this case Edge* or pointer-to-Edge, but you are using array semantics with it. E[nEdges] is not a pointer, which means you have to use the . operator.

Basically, when you use array semantics you lose the pointer-ness of the variable.

E is of type Edge*, E[x] is of type Edge.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409176

You use E as an array, and the separate members inside that array are not pointers, so you have to use the dot-operator to access elements.

On the other hand you have g which is a pointer to a single graph structure, and as a pointer you use the -> operator.

However, you could access the array E as pointers, and the variable g as an array. For example, the following two statements are both exactly the same:

E[0].from = i;

(E + 0)->from = i;

And you can access g as an array like this:

g[0].nodes = x;

Upvotes: 2

Related Questions