ПрограммированиеBackend C разработчик

Как работает оператор sizeof в языке C, и какие подводные камни существуют при его использовании?

Проходите собеседования с ИИ помощником Hintsage

Ответ

Оператор sizeof используется для определения размера типа или объекта в байтах на этапе компиляции. Он часто нужен для выделения памяти, расчёта размеров структур и массивов.

Пример:

int a; printf("%zu ", sizeof(a)); // размер переменной a типа int printf("%zu ", sizeof(int)); // размер типа int

Особенности:

  • sizeof возвращает size_t, всегда >= 0.
  • Для массивов sizeof(array) возвращает размер всего массива, а не размера указателя.
  • При передаче массива в функцию вы теряете информацию о его размере.

Пример подводного камня:

void foo(int arr[]) { printf("%zu ", sizeof(arr)); // выведет размер указателя, а не массива! } int arr[10]; foo(arr); // sizeof(arr) == 40 (обычно), sizeof(arr на уровне foo) == 8 (обычно)

Вопрос с подвохом

Что вернёт выражение sizeof('a') в языке C?

Ответ: Несмотря на то, что 'a' выглядит как char, в выражении sizeof('a') результат равен размеру типа int, т.к. символьная константа в C — это int.

Пример:

sizeof('a') // обычно 4, а не 1

Примеры реальных ошибок из-за незнания тонкостей темы


История

В проекте выделяли память для копирования строки так: malloc(strlen(str) * sizeof(char)), забыв про нулевой символ. Это привело к потере последнего байта и появлению багов при работе с функциями стандартной библиотеки обработки строк.

История

Один из модулей использовал sizeof(arr) в функции, ожидая размер всей структуры, но получил только размер указателя. В результате в память писали слишком мало данных, что вызывало повреждение кучи.

История

Разработчик решил использовать sizeof('a') для выделения памяти под одну букву, ожидая 1 байт, а получил 4 (или 8) — это вылилось в неэффективном расходе памяти и проблемах в коде, зависимом от ожидаемого размера.