Я вижу, что люди часто пишут код C, такой как:
char *ptr = malloc(sizeof(char)*256);
Это действительно необходимо? В стандарте говорится это sizeof(char)==1
по определению, не делает это имеет смысл только для записи:
char *ptr = malloc(256);
Да, C определяет sizeof (char)
как всегда равным 1 (и C ++ тоже).
Тем не менее, как правило, я бы посоветовал что-то вроде:
char *ptr = malloc(256 * sizeof(*ptr));
Таким образом, когда ваш босс говорит что-то вроде: «О, кстати, мы только что получили заказ из Китая, поэтому нам нужно обработать все три китайских алфавита. ASAP », вы можете изменить его на:
wchar_t *ptr // ...
, а остальное останется прежним. Учитывая, что у вас будет около 10 миллионов головных болей, пытаясь справиться с i18n хотя бы на полпути, устранение даже нескольких имеет смысл. Это, конечно, предполагает обычный случай, когда ваши char
действительно предназначены для хранения символов - если это просто какой-то необработанный буфер, и вам действительно нужно 256 байт памяти, независимо от того, сколько (из нескольких) символов, которые могут быть, вам, вероятно, следует придерживаться malloc (256)
и покончить с этим.
Это может быть правдой, но это верно только для конкретного случая char
.
Лично я считаю хорошим тоном использовать форму malloc (sizeof (char) * 256)
, потому что кто-то, меняя тип или копируя код для той же цели с другим типом, может пропустить тонкости того дела.
Проблема даже не должна существовать. Вам следует использовать более элегантную идиому, записывая свои malloc
как
ptr = malloc(N * sizeof *ptr)
т.е. по возможности избегайте упоминания имени типа. Имена типов предназначены для объявлений, а не для операторов.
Таким образом, ваши malloc
всегда будут независимы от типа и будут выглядеть согласованно. Тот факт, что умножение на 1 является лишним, будет менее очевидным (поскольку некоторых людей умножение на sizeof (char)
раздражает).
Хотя с технической точки зрения нет ничего плохого в написании sizeof(char)
, это говорит о том, что автор не знаком с языком C и тем фактом, что sizeof(char)
определяется как 1. В некоторых проектах, над которыми я работал, мы действительно искали случаи 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 для соответствия строке.
Да, технически они эквивалентны. Это просто вопрос стиля - использование sizeof
для каждого распределения снижает вероятность того, что вы пропустите его, когда оно вам действительно нужно.
Они эквивалентны, но лучше оставаться последовательными. Это также делает его более ясным, поэтому становится очевидным, что вы имеете в виду. Если тип когда-либо изменится, легче узнать, какой код нужно обновить.