2016-09-07 4 views
4

Это фактический код C от Pthreads:Использование таНос в Pthreads

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

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

Почему они решили таНос * Parms вместо ThreadParms? Похоже, что он выделяет только указатель (который был бы ошибкой), но он, по-видимому, выделяет размер всей структуры. Это верно?

+0

'sizeof' может принимать тип или переменную – redneb

+1

Я предполагаю, что я принимаю это, так как они решили использовать malloc, почему бы не просто ThreadParms в sizeof()? Тем не менее, я исповедую синтаксис sizeof (* что-то), бросил меня немного. Это мой недостаток. – Jiminion

+1

'* params' разделяет' ThreadParams' тип, поэтому вы будете 'malloc' полный размер структуры с помощью любого метода. Как говорят ответы, это экономит на расходах на обслуживание, если тип 'params' будет когда-либо изменяться. – yano

ответ

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, так что код является правильным.

+0

Я вижу это. Но они этого не сделали, не так ли? Из-за (ненужного) литья malloc? ЛОЛ. (Я думаю, они бросили его, чтобы сделать код C++ совместимым, но я не уверен.) – Jiminion

+0

@Jiminion Я уверен, что это тоже для C++. – dasblinkenlight

+0

Это файл .c. (Create.c). Может быть, это привычка. (И я не хочу вдаваться в актерский состав или не бросать malloc() debate ....) :) – Jiminion

3

*parms имеет ThreadParms типа так размер OK

Это иногда рассматривается как лучше сделать так, чем старый sizeof(ThreadParms), поэтому, если типа parms изменяет размер следующим образом (присвоение и sizeof утверждения находится на та же линия)

(однако это не совершенны и не защищает от/ошибки пасты копирования при выделении какой-либо другой тип с той же самой линии, но в целом лучше)

+0

Справа. Но в этом случае вам все равно придется менять заклинание malloc, нет? – Jiminion

+0

не нужно бросать, потому что malloc возвращает void * (общий указатель). Я говорю это, но я узнал, что всего несколько дней назад и должен был сделать компиляцию, чтобы убедиться: –

3

Почему они выбрали marmoc * parms вместо ThreadParms.

Общепринятой практикой является использование в случае, если тип parms изменится в будущем, тогда обслуживание будет проще. Но использование ThreadParms будет работать так же хорошо.

Похоже, что выделяет только указатель (что было бы ошибка), но, по-видимому распределения размера всей структуры. Это правильно?

Нет. Это фактически эквивалентно использованию sizeof(ThreadParms) как оператор SizeOf нужна только информация о типе и не оценивает свой операнд (кроме C99 Variable Length Arrays). Тип *parms - ThreadParms, и все это sizeof необходимо знать.

Сторона примечания: литье до ThreadParms * не нужно в C, так как void * может быть назначен любой другой указатель данных.

+0

не будет определять sizeof (char *) для указателя? (Не символ?) – Jiminion

+0

Да. Но это не так. 'sizeof' требуется только * type *' * parms', который является 'ThreadParms'. – usr

+0

@dasblinkenlight Да, просто уточняя «оценку точки операнда». – Jiminion

Смежные вопросы