这是来自Pthreads的实际C代码:
ThreadParms *parms = NULL;
if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL)
{
goto FAIL0;
}
parms->tid = thread;
parms->start = start;
parms->arg = arg;
为什么他们选择malloc *parms而不是ThreadParms?看起来它只分配了一个指针(这将是一个错误),但它显然分配了整个结构的大小。这是正确的吗?
这是C语言中一个常见的技巧——用解引用指针表达式代替实际的类型。
基本原理如下:如果你有
some_type *some_var = malloc(sizeof(*some_var));
,然后将some_type
更改为some_other_type
,代码将继续正常工作,只需更改一次。
但是,如果你以
开头some_type *some_var = malloc(sizeof(some_type));
那么你必须在两个地方改变some_type
:
some_other_type *some_var = malloc(sizeof(some_other_type));
,否则你的代码会有错误。
看起来它只分配了一个指针(这将是一个错误)
星号使sizeof
计算为整个struct
的大小,因此代码是正确的。
*parms
为ThreadParms
类型,大小OK
有时这样做比旧的sizeof(ThreadParms)
更好,所以如果parms
的类型改变了大小,下面是(赋值和sizeof
语句在同一行)
(然而,这并不完美,并且不能防止在为同一行分配其他类型时出现复制/粘贴错误,但通常情况下更好)
为什么他们选择malloc *parms而不是ThreadParms。
这是一种常见的做法,以便万一parms
的类型在将来发生变化,那么维护就更容易了。但是使用ThreadParms
也可以。
看起来它只分配了一个指针(它应该是一个指针)错误),但它显然分配了整个结构的大小。这是正确的吗?
。它实际上相当于使用sizeof(ThreadParms)
作为sizeof操作符,只需要类型信息,而不计算其操作数(除了C99可变长度数组)。*parms
的类型是ThreadParms
,这就是sizeof
所需要知道的。
旁注:在C语言中没有必要强制转换为ThreadParms *
,因为void *
可以被分配给任何其他数据指针。