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

StackOverflow https://stackoverflow.com/questions/1011806

Вопрос

При использовании 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. Экономический и культурный комментарий ".

<Ол>
  • Статистика: 2,0% от sizeof берется из char и 1,5% - из unsigned char . Страница 1033 в версии 1.2 книги.
  • стр. 1037.
  •   

    Количество битов в представлении символьного типа равно   не имеет значения. По определению количество   байтов в байте тип символа   один.      

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

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

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top