1
#include <stdlib.h>

struct timer_list
{
};

int main(int argc, char *argv[])
{
  struct foo *t = (struct foo*) malloc(sizeof(struct timer_list));
  free(t);
  return 0;
}

Why the above segment of code compiles (in gcc) and works without problem while I have not defined the foo struct?

alk
  • 69,737
  • 10
  • 105
  • 255
Dragno
  • 3,027
  • 1
  • 27
  • 41
  • I'm gonna go with because you are using it as a pointer, and not accessing any of the memory, so the compiler doesn't need to know anything about the structure at that point. I have no idea if that is right, hence I am not making it as an answer – Dan F Jan 08 '13 at 14:33
  • Don't cast the return of `malloc`: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Jens Gustedt Jan 08 '13 at 14:37

2 Answers2

7

because in your code snippet above, the compiler doesn't need to know the size of struct foo, just the size of a pointer to struct foo, which is independent of the actual definition of the structure.

Now, if you had written:

struct foo *t = malloc(sizeof(struct foo));

That would be a different story, since now the compiler needs to know how much memory to allocate.

Additionally, if you at an point you try to access a member of a struct foo* (or dereference a pointer to a foo):

((struct foo*)t)->x = 3;

The compiler would also complain, since at this point it needs to know the offset into the structure of x.


As an aside, this property is useful to implement an Opaque Pointer.

John Ledbetter
  • 13,557
  • 1
  • 61
  • 80
  • 2
    ... or `struct foo *t = malloc(sizeof *t);` which is the safer way of writing such a call. At least in my opinion. :) – unwind Jan 08 '13 at 14:36
  • @unwind -- agreed, just leaving the code the way the OP wrote it :) – John Ledbetter Jan 08 '13 at 14:36
  • And what about free(t)? Can the compiler free the memory without knowing the real size of the struct? – Dragno Jan 08 '13 at 14:57
  • 1
    @Dragno I suspect it can, because that information is not stored inside the structure itself. – John Ledbetter Jan 08 '13 at 15:06
  • Minuscule nitpick, the compiler needs not only know the size of a `struct foo*` but also the representation and alignment requirements. But the representation and alignment requirements of all pointers to structure types must be the same (6.2.5 (28), ditto for pointers to unions), so that still doesn't require any knowledge about `struct foo` (other than that it is a `struct`). – Daniel Fischer Jan 08 '13 at 21:05
0

"And what about free(t)? Can the compiler free the memory without knowing the real size of the struct?" No, compiler doesn't free anything. Free() is just a function with input parameter void *.

user1869474
  • 57
  • 1
  • 1
  • 6
  • Free() has parameter type void * because it is designed to accept any parameter. Free() deallocates memory that is allocated for a certain pointer of any type. – Kevin Jan 08 '13 at 18:21