简体   繁体   中英

Use of malloc in Pthreads

This is actual C code from Pthreads:

ThreadParms *parms = NULL; 
if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
    {
      goto FAIL0;
    }

  parms->tid = thread;
  parms->start = start;
  parms->arg = arg;

Why did they choose to malloc *parms instead of ThreadParms? It looks like it is allocating only a pointer (which would be an error), but it apparently allocating the size of the whole structure. Is this correct?

This is a common trick in C - using dereference pointer expression in place of the actual type.

The rationale is as follows: if you have

some_type *some_var = malloc(sizeof(*some_var));

and then change some_type to some_other_type , the code would continue working fine with only one change.

However, if you start with

some_type *some_var = malloc(sizeof(some_type));

then you have to change some_type in two places:

some_other_type *some_var = malloc(sizeof(some_other_type));

or your code would have an error.

It looks like it is allocating only a pointer (which would be an error)

The asterisk makes sizeof evaluate to the size of the entire struct , so the code is correct.

*parms is of ThreadParms type so size is OK

It's sometimes seen as better to do like this than the old sizeof(ThreadParms) , so if type of parms changes the size follows (the assignment and the sizeof statement are on the same line)

(however that's not perfect and does not protect against a copy/paste error when allocating some other type with the same line, but it's generally better)

Why did they choose to malloc *parms instead of ThreadParms.

It's a common practice to use so in case if the type of parms changes in the future, then maintenance is easier. But using ThreadParms would work just as well.

It looks like it is allocating only a pointer (which would be an error), but it apparently allocating the size of the whole structure. Is this correct?

No. It's actually equivalent to using sizeof(ThreadParms) as the sizeof operator only needs the type information and it doesn't evaluate its operand (except C99 Variable Length Arrays ). The type of *parms is ThreadParms and that's all sizeof needs to know.

Side note: the cast to ThreadParms * is unnecessary in C as void * can be assigned any other data pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM