这是来自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?看起来它只分配一个指针(这将是一个错误),但它显然分配了整个结构的大小。这是对的吗?
答案 0 :(得分:5)
这是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
的大小,因此代码是正确的。
答案 1 :(得分:3)
*parms
属于ThreadParms
类型,因此尺寸正常
有时看起来这样做比旧sizeof(ThreadParms)
更好,所以如果parms
的类型改变了大小,则(赋值和sizeof
语句在同一行上)
(但是这并不完美,并且在使用相同的线路分配其他类型时不能防止复制/粘贴错误,但通常更好)</ p>
答案 2 :(得分:3)
为什么他们选择malloc * parms而不是ThreadParms。
如果parms
的类型在将来发生变化,那么使用它是一种常见的做法,那么维护就更容易了。但使用ThreadParms
也可以。
看起来它只分配一个指针(这将是一个 错误),但它显然分配整个结构的大小。 这是对的吗?
没有。它实际上等同于使用sizeof(ThreadParms)
,因为sizeof运算符只需要类型信息,并且它不会评估其操作数(C99 Variable Length Arrays除外)。 *parms
的类型为ThreadParms
,并且所有sizeof
都需要知道。
旁注:C中不需要转换为ThreadParms *
,因为void *
可以分配任何其他数据指针。