Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how av_freep in ffmpeg works?

Tags:

c

pointers

ffmpeg

I have some questions regarding void pointer in C. I found out the following code, part of ffmpeg that I couldn't understand... Could someone explain to me how it works?

void av_freep(void *arg)
{
        void *val;

        memcpy(&val, arg, sizeof(val));
        memcpy(arg, &(void *){ NULL }, sizeof(val));
        av_free(val);
}

and later it's called like this:

char *str;
av_freep(&str);

my questions:

  1. how passing address of str (&str) doesn't trigger "incompatible type" warning when it's compiled? Shouldn't &str type is become char**?
  2. what's the meaning of &(void *){ NULL } in one of memcpy parameter?
  3. why it's trying to free "val" which is not allocated?

Thanks!

like image 373
Billy Bob Avatar asked Aug 11 '16 08:08

Billy Bob


2 Answers

how passing address of str (&str) doesn't trigger "incompatible type" warning when it's compiled? Shouldn't &str type is become char**?

It is, and char** is implicitly convertible to void * (because every pointer type is implicitly convertible to void *).

what's the meaning of &(void *){ NULL } in one of memcpy parameter?

It's a compound literal (even though void * isn't a compound type). The compiler allocates a constant void * holding NULL, and then (&(void *){ NULL }) is a pointer to that. It's essentially equivalent to:

static void* const temp = NULL;
memcpy(arg, &temp, sizeof(val));
like image 99
user253751 Avatar answered Oct 01 '22 16:10

user253751


how passing address of str (&str) doesn't trigger "incompatible type" warning when it's compiled? Shouldn't &str type is become char**?

This is because of fact that av_freep() parameter is void * i.e. it is compatible with any type of data pointers. Of course code would be clearer if it was e.g. void **. In that case we explicitly see that function erases our pointer to avoid accidental future dereferences. But then we should use ugly casts for almost all usages of function, because void ** is not compatible with arbitrary data pointer types.

what's the meaning of &(void *){ NULL } in one of memcpy parameter?

It is so called compound literal, you may think about it like an local object with type void * that is initialised with NULL.

like image 34
Sergio Avatar answered Oct 04 '22 16:10

Sergio