В C есть malloc (256) и malloc (sizeof (char) * 256) эквивалент?

Я вижу, что люди часто пишут код C, например:

char *ptr = malloc(sizeof(char)*256);

Это действительно необходимо? В стандарте говорится, что sizeof(char)==1 по определению, так что не имеет смысла просто писать:

char *ptr = malloc(256);

Спасибо, Бода Сидо.

Ответ 1

Да, C определяет sizeof(char) равным 1, всегда (и С++ тоже).

Тем не менее, как правило, я бы посоветовал что-то вроде:

char *ptr = malloc(256 * sizeof(*ptr));

Таким образом, когда ваш босс говорит что-то вроде: "О, BTW, мы получили заказ из Китая, поэтому нам нужно обрабатывать все три китайских алфавита как можно скорее", вы можете изменить его на:

wchar_t *ptr // ...

а остальные могут оставаться неизменными. Учитывая, что у вас будет около 10 миллионов головных болей, которые пытаются справиться с проблемой i18n даже на полпути разумно, устранение даже нескольких из них стоит того. Это, конечно, предполагает обычный случай, когда ваш char на самом деле предназначен для хранения символов - если это просто некорректный буфер, и вы действительно хотите 256 байт памяти, независимо от того, сколько (нескольких) символов возможно, вы должны придерживаться malloc(256) и делать с ним.

Ответ 2

Проблема не должна существовать. Вы должны принять более элегантную идиому написания своего malloc как

ptr = malloc(N * sizeof *ptr)

то есть. избегайте упоминания имени типа как можно больше. Имена типов для деклараций, а не для операторов.

Таким образом, ваш malloc будет всегда независимым от типа и будет выглядеть последовательным. Тот факт, что умножение на 1 является излишним, будет менее очевидным (поскольку некоторые люди находят умножение на sizeof(char) раздражающим).

Ответ 3

Они эквивалентны, но хорошо оставаться последовательными. Это также делает его более явным, так что это очевидно, что вы имеете в виду. Если тип когда-либо изменяется, легче выяснить, какой код необходимо обновить.

Ответ 4

Это может быть правдой, но это верно только для этого конкретного случая char.

Я лично считаю хорошей формой использовать форму malloc(sizeof(char) * 256), потому что кто-то, изменяющий тип, или копирование кода для аналогичной цели с другим типом, может пропустить тонкости этого случая.

Ответ 5

В то время как нет ничего технически неправильного в написании sizeof(char), это говорит о том, что автор не знаком с C и тот факт, что sizeof(char) определяется как 1. В некоторых проектах, над которыми я работал, мы на самом деле grep для экземпляры sizeof(char) в качестве индикатора того, что код может быть некачественным.

С другой стороны, ptr = malloc(count * sizeof(*ptr)); - очень полезная документация и идиома ошибки, и имеет смысл, даже если sizeof(*ptr) равно 1. Однако ему должно предшествовать if (count > SIZE_MAX/sizeof(*ptr)) { /* handle overflow */ } или у вас есть серьезная ошибка, Это может быть особенно актуально при распределении массивов wchar_t или сложных структур той же длины, что и входная строка, например, при преобразовании строки UTF-8 в строку wchar_t или построении DFA для соответствия строке.

Ответ 6

Да, они технически эквивалентны. Это просто вопрос стиля - использование sizeof для каждого распределения делает вас менее вероятным пропустить его, когда вам действительно это нужно.