Нужно ли умножать на sizeof (char) при манипулировании памятью?
-
06-07-2019 - |
Вопрос
При использовании malloc и аналогичных манипуляциях с памятью могу ли я полагаться, что sizeof (char) всегда равен 1?
Например, мне нужно выделить память для N элементов типа char
. Нужно ли умножать на sizeof (char)
:
char* buffer = malloc( N * sizeof( char ) );
или я могу положиться, что sizeof (char) всегда равен 1 и просто пропускаю умножение
char* buffer = malloc( N );
Я полностью понимаю, что sizeof
оценивается во время компиляции, а затем компилятор может даже скомпилировать умножение, поэтому потеря производительности будет минимальной и, скорее всего, нулевой.
Я спрашиваю в основном о ясности и переносимости кода. Является ли это умножение когда-либо необходимым для типа char
?
Решение
Хотя в этом нет необходимости, я считаю хорошей практикой оставлять в sizeof (char), потому что это делает код более читабельным и позволяет избежать использования магического числа. Кроме того, если код необходимо изменить позже, чтобы вместо символа он искажал размер чего-либо в указателе для этого объекта, его было бы проще изменить, чем если бы у вас был только «1».
Другие советы
По определению sizeof (char) всегда равен 1. Один байт - это размер символа в C, независимо от количества бит в байте (8 на обычном настольном процессоре).
Типичным примером, когда один байт не равен 8 битам, является PDP-10 и другие старые, мини-компьютерные архитектуры с 9/36 битными байтами. Но я считаю, что байты, которые не равны 2 ^ N, становятся чрезвычайно необычными
Кроме того, я думаю, что это лучший стиль:
char* buf1;
double* buf2;
buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);
потому что он работает независимо от типа указателя.
sizeof (char)
всегда равно 1 независимо от типа манипуляций с памятью.
Однако sizeof (TCHAR)
может варьироваться в зависимости от параметров вашего компилятора.
Я считаю это своего рода антишаблоном . Это говорит о том, что программист не совсем знал, что он делает, что сразу бросает остальную часть кода в сомнительный свет.
Конечно, это не так (цитируя Википедию) «неэффективно», но я нахожу это «далеко не оптимальным». Это ничего не стоит во время выполнения, но оно загромождает код ненужным мусором, все время сигнализируя, что кто-то посчитал это необходимым.
Также обратите внимание, что выражение не анализируется как вызов функции: sizeof
не является функцией. Вы не вызываете функцию, передающую магический символ char
. Вы применяете встроенный оператор унарного префикса sizeof
к выражению, и в этом случае ваше выражение является приведением к типу char
, который в C записывается как <код> (символ) код>. р>
Вполне возможно и настоятельно рекомендуется, когда это возможно, использовать sizeof
для других выражений, тогда он будет давать размер значения выражения:
char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);
Это будет печатать 1
всегда во всех соответствующих реализациях C.
Я также полностью согласен с Дэвидом Курнапо и считаю, что повторение типа name в malloc ()
, чтобы также было своего рода анти-модель. р>
Вместо
char *str;
str = malloc(N * sizeof (char));
что многие пишут для выделения строкового буфера с N-символьной емкостью, я бы пошел с
char *str;
str = malloc(N * sizeof *str);
Или (только для строк) не указывайте sizeof
, как указано выше, но это, конечно, более общий подход и работает так же хорошо для любого типа указателя.
Это не обязательно. См. здесь (например).
sizeof (char)
определяется стандартом C как всегда 1 (байт). Обратите внимание, что поскольку sizeof
возвращает количество байтов , количество бит на байт не имеет значения (и в любом случае на практике это 8).
Еще кое-что, что нужно иметь в виду, это то, что компилятор статически знает, что значение sizeof (char) равно 1, а также знает, что умножение числа на статическое 1 означает, что умножение не требуется; компилятор оптимизирует его. Проблемы исполнения не должны входить в рассмотрение на этих основаниях.
От " Новый стандарт C. Экономический и культурный комментарий ".
<Ол> char
и 1,5% - из unsigned char
. Страница 1033 в версии 1.2 книги. Количество битов в представлении символьного типа равно не имеет значения. По определению количество байтов в байте тип символа один. р>
Рекомендации по кодированию Разработчики иногда ассоциировать байт как всегда содержащий восемь бит На хостах где то тип символа 16 бит, это может привести к неверному предположению, что применение sizeof к типу символов вернет значение 2. Эти вопросы обсуждаются в другом месте.
Использование sizeof (char) делает ваш код более читабельным и переносимым.
На x86 мы все знаем, что символ равен 1 байту. Но явное его написание помогает прояснить ваши намерения, что всегда хорошо.
Кроме того, что если ваш код будет помещен на другую платформу, где символ не равен 1 байту. Что, если символ был только 4 битами вместо этого?
Согласен, в этом нет необходимости, но он не замедляет время выполнения и окупится в том редком случае, когда вам нужно перенести код на другую архитектуру.