1

In the book "C Programming: A Modern Approach, chapter 17.4 introduced the function free() which has the prototype of the following form: void free(void *ptr). As the author outlines several examples involving dynamic storage using malloc(), the following snippet of quasi-code is encountered:

struct node {
  int value;
  struct node *next;
};

struct node *delete_from_list(struct node *list, int n)
{
  struct node *cur, *prev;
  . 
  .    /*Will explain the relevant part of this section as it pertains to the question (bullet 3 below) */
  .
  free(cur); /* <--- my question is about this line */
}

The important points are:

  1. there is a data type known as struct node that has two fields
  2. there is a pointer to struct node named cur
  3. in the delete_from_list function, cur will eventually get assigned some address in the heap. In particular, it will get assigned to a chunk of memory with data type struct node.

With those 3 points established, we can attend to my question: why does calling the function free() with the argument cur work without issue? cur is not of type pointer to void. I assume that means there is some type of implicit (under the hood) type casting occurring that changes cur's datatype from pointer to struct node to pointer to void. Is that the case? If so, is there a general rule about implicit type casting of pointers as argument when it comes to functions calls?

Christopher Moore
  • 15,626
  • 10
  • 42
  • 52
S.C.
  • 231
  • 1
  • 8
  • 1
    `cur will eventually get assigned some address in the heap` If you look at the line where this happens, you'll most likely find a `malloc` call or similar. That call returns a `void *` as well, regardless of what type of data you are using it for. The malloc/free functions are about memory de/allocation, not types. – dxiv Sep 10 '20 at 23:29

1 Answers1

3

Any object pointer type may be freely converted to or from a void * without a cast.

Section 6.3.2.3p1 of the C standard states:

A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

Also, the free function may only be passed a pointer that was returned from one of the malloc family of functions, and these all return a void *.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • I guess I am unsure of how to interpret your first sentence. Consider an instance where I have the following sequence of statements: `int *ptr; int a=7; ptr=&a; *ptr=6`. With the final statement (the dereference) clearly the compiler knows that `ptr` needs to be treated as a pointer to integer (i.e. the compiler chooses NOT TO convert `ptr` to `void *`. Why? How does it know in this aforementioned instance NOT TO convert `ptr` to `void *` but in my post example (with `free`) it knows TO convert the pointer to `void *`. – S.C. Sep 10 '20 at 23:53
  • @S.Cramer Since `ptr` is a pointer to an `int`, dereferencing it gives you an `int`. when passing to `free`, the type of the parameter is `void *` which is why there is an implicit conversion to `void *` . – dbush Sep 11 '20 at 01:01
  • ohhhhh. Got it. Thank you! – S.C. Sep 11 '20 at 01:40