В C эквивалентны ли malloc (256) и malloc (sizeof (char) * 256)? - PullRequest
11 голосов
/ 02 июля 2010

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

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

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

char *ptr = malloc(256);

Ответы [ 6 ]

23 голосов
/ 02 июля 2010

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

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

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

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

wchar_t *ptr // ...

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

6 голосов
/ 02 июля 2010

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

ptr = malloc(N * sizeof *ptr)

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

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

4 голосов
/ 02 июля 2010

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

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

4 голосов
/ 02 июля 2010

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

2 голосов
/ 02 июля 2010

Хотя технически нет ничего плохого в написании 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 для соответствия строке.

1 голос
/ 02 июля 2010

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

...