Нужно ли умножать sizeof (char) при манипулировании памятью?

При использовании malloc и выполнении подобной манипуляции с памятью я могу полагаться на sizeof (char) всегда 1?

Например, мне нужно выделить память для N элементов типа char. Требуется умножение на sizeof( char ):

char* buffer = malloc( N * sizeof( char ) );

или я могу полагаться на sizeof (char), всегда равным 1, и просто пропустить умножение

char* buffer = malloc( N );

Я полностью понимаю, что sizeof оценивается во время компиляции, а затем компилятор может даже скомпилировать умножение, и поэтому оценка производительности будет минимальной и, скорее всего, нулевой.

Я прошу в основном о ясности кода и переносимости. Является ли это умножение когда-либо необходимым для типа char?

Ответы

Ответ 1

В то время как это не обязательно, я считаю хорошей практикой оставить в sizeof (char), потому что он делает код более читаемым и позволяет избежать использования магического числа. Кроме того, если код нужно изменить позже, чтобы вместо char он перераспределял размер чего-то в указатель для этого объекта, проще изменить код, чем если бы у вас было только "1".

Ответ 2

По определению 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);

потому что он работает независимо от типа указателя.

Ответ 3

sizeof(char) всегда 1 независимо от того, какой тип манипуляции с памятью вы делаете.

Однако sizeof(TCHAR) может меняться в зависимости от ваших параметров компилятора.

Ответ 4

Я рассматриваю это как anti-pattern. Это сигнализирует, что программист не совсем знал, что он/она делает, что сразу бросает остальную часть кода в сомнительный свет.

Конечно, это не (цитирование Википедии) "неэффективно", но я считаю его "далек от оптимального". Это не стоит ничего во время выполнения, но он загромождает код ненужным барахлом, все время сигнализируя, что кто-то считает это необходимым.

Также обратите внимание, что выражение не анализируется как функция-вызов: sizeof не является функцией. Вы не вызываете функцию, передавая ей магический символ char. Вы применяете встроенный оператор унарного префикса sizeof к выражению, и ваше выражение в этом случае относится к типу char, который в C записывается как (char).

Совершенно возможно и настоятельно рекомендуется, когда это возможно, использовать sizeof для других выражений, тогда он даст размер значения выражения:

char a;
printf("A char size is %u\n", (unsigned int) sizeof a);

Это будет печатать 1, всегда, во всех соответствующих реализациях C.

Я также очень согласен с Дэвидом Курнерау и считаю, что повторять имя типа в malloc() -call также является своего рода анти-шаблоном.

Вместо

char *str;

str = malloc(N * sizeof (char));

что многие напишут для выделения буфера строк с емкостью N-символа, я бы пошел с

char *str;

str = malloc(N * sizeof *str);

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

Ответ 5

Это не обязательно. См. здесь (например).

sizeof(char) определяется стандартом C, всегда равным 1 (байт). Обратите внимание, что поскольку sizeof возвращает количество байтов, количество бит на байт не имеет значения (и в практическом смысле это 8 в любом случае).

Ответ 6

Что-то еще нужно иметь в виду, так это то, что компилятор статически знает значение sizeof (char) равным 1, и он также знает, что умножение числа на статический 1 означает, что умножение не нужно делать; компилятор оптимизирует его. Озабоченность выступления не должна входить в рассмотрение на этих основаниях.

Ответ 7

Из "Нового стандарта C. Экономический и культурный комментарий".

  • Статистика: 2,0% от размераof взяты из char и 1,5% - от unsigned char. Страница 1033 в версии 1.2.
  • стр. 1037.

Число бит в представлении типа символа равно не имеет значения. По определению число байтов в байте, тип символа равен один.

Рекомендации по кодированию Разработчики иногда ассоциировать байт, как всегда содержащий восемь бит. На хостах, где тип символа - 16 бит, это может приводят к ошибочному предположению, что применение sizeof к типу символа вернет значение 2. Эти вопросы обсуждаются в других местах.

Ответ 8

Использование sizeof (char) делает ваш код более читабельным и портативным.

На x86 мы все знаем, что символ 1 байт. Но прямое его изложение помогает сделать ваши намерения более ясными, что всегда хорошо.

Кроме того, что, если ваш код будет помещен на другую платформу, где символ не является 1 байтом. Что, если вместо символа было всего 4 бита?

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