0

I was trying to implement graph using an adjacency list.While initializing head as NULL in the for loop in CreateGraph method, head is being reffered using '.' instead of '->'. I cannot understand the difference. When should we use '.' and when '->'. And why do it gives an error , when I use -> operator for head.

 struct AdjListNode
 {
int dest;
struct AdjListNode* next;
};


struct AdjList
{
struct AdjListNode *head; // pointer to head node of list
};


struct Graph
{
int V;
struct AdjList* array;
};

// A utility function to create a new adjacency list node
struct AdjListNode* newAdjListNode(int dest)
{
struct AdjListNode* newNode =
        (struct AdjListNode*) malloc(sizeof(struct AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}

// A utility function that creates a graph of V vertices
struct Graph* createGraph(int V)
{
struct Graph* graph = (struct Graph*) malloc(sizeof(struct Graph));
graph->V = V;

// Create an array of adjacency lists. Size of array will be V
graph->array = (struct AdjList*) malloc(V * sizeof(struct AdjList));

// Initialize each adjacency list as empty by making head as NULL
int i;
**for (i = 0; i < V; ++i)
    graph->array[i]->head = NULL;**

return graph;
}
  • `graph->array[i]` is not a pointer. – tkausl Feb 19 '17 at 08:55
  • Answers to such basic questions can be found in any text book. If you don't have one yet, [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) is a good place to start. – R Sahu Feb 19 '17 at 08:55

2 Answers2

0

Well, this goes back before C++, and is inherited from C.

Basically you use '->' on a pointer, and '.' on a reference (or to say it more simple - plain value). What is inherited from C is that pointers and arrays are interchangeable most of the time. E.g. in

AdjList *array = /* allocate some memory */
array[0].head = nullptr;

the '[]' iterator gives you a reference to the 0-th field.

What I wonder about your example, is that it does not use some of the basic nice features of C++:

  • you can initialize the fields in a constructor to prevent all this initialization from the outside
  • using a std::vector instead of a self-maintained array may be much easier
schroder
  • 181
  • 1
  • 3
  • there are dozens of real life examples when both or either are banned from happening. vectors to be avoided on some embedded systems that have memory manager that does not clean up after process exited (and next instance, can be fired, inheriting the memory). Or due ban on std:: namespace use by code review standard. Initialization due to compiler switches or code review standards (easier manual check-up) – Swift - Friday Pie Feb 19 '17 at 09:05
  • @Swift how is `std::vector` bad for cleaning up memory? – Ap31 Feb 19 '17 at 09:29
  • @Ap31: The C++ standard does acknowledge the existence of so-called free-standing implementations which must support only a very reduced feature set of the language. But in this case, I think it's a red herring; if you cannot use `std::vector` because of certain memory constraints, then you probably cannot use `new` or even `malloc` either. Banning `std::` or initialisation lists sounds more like an issue with 20-year old code bases (or 20-year old compilers) to me. It's unlikely that anything of this is remotely relevant to the OP. – Christian Hackl Feb 19 '17 at 10:03
  • @schroder Even i was thinking on going for vectors. That will make things easy to edit. – Vaibhav Tandon Feb 19 '17 at 12:29
  • @ap31 std::vector uses reallocation, which is sometimes banned, sometimes not even possible. Yes it is red herring, but _physically_ those herrings are just as numerous as consumer calss or standartized systems, and reforms in them cost not only worktime but possible human lives. It is more of a social, phylosophic, managent if you like, problem rather than aprogrammer's problem – Swift - Friday Pie Feb 20 '17 at 16:08
-1

graph->array[i] is an object, not a pointer so you should access it's members trough . operator. -> is used when you have a pointer to structure/class and want to access its members w/o dereferencing it (aka (*pointer).field).

Also, keep in mind that in C++ you should rather use new&delete instead of malloc&free and nullptr instead of NULL.

Kamil Koczurek
  • 696
  • 5
  • 15
  • I dont get it, it is an object but a pointer as well. Can you please give an example for this. – Vaibhav Tandon Feb 19 '17 at 09:06
  • No, you either have an object or a pointer to object. Eg. `auto ptr = &x; auto& ref = x`, `ptr` is a pointer and you *have* to use `->`, `ref` is a reference and you are obligated to use `.`, there are no exceptions (unless you overload `->` operator, but as far as I know it's not possible yet). – Kamil Koczurek Feb 19 '17 at 09:49
  • Pointers **are** objects. In your example, the variable named `ptr` refers to that pointer object. `ref`, in contrast, is the name of a reference and references are not themselves objects. You can also create a reference to a pointer; the syntax then becomes `->` because once initialised, the reference is treated exactly like the pointer object it refers to. For example, `auto& reference_to_pointer = ptr; reference_to_pointer->whatever;`. – Christian Hackl Feb 19 '17 at 10:04
  • P.S.: You should *not* use `new[]` and `delete[]`. `std::vector` is always a superior alternative to dynamic arrays allocated with `new[]`. – Christian Hackl Feb 19 '17 at 10:08