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

Как в С инициализируются переменные различных видов хранения (автоматические, статические, глобальные)? Как это сказывается на безопасности и корректности работы программы?

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

Ответ

В языке C переменные инициализируются по-разному в зависимости от спецификатора хранения:

  • Автоматические (локальные) переменные: имеют неинициализированное (мусорное) значение, если явно не задать начальное значение. Их содержимое — та память стека, что была до этого.
  • Статические локальные и глобальные переменные (static, extern): всегда инициализируются нулями (для скаляров — 0, для указателей — NULL) или заданным значением на этапе компоновки.

Пример различий:

void example() { int a; // автоматическая, не инициализирована static int b; // инициализирована как 0 printf("a=%d, b=%d ", a, b); } int c; // глобальная, инициализирована как 0

Ошибки складываются из неверного предположения об инициализации. Для безопасности всегда инициализируйте переменные явно.

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

Инициализируется ли автоматическая локальная переменная значением 0, если она объявлена на уровне функции вне блока?

Ответ:

Нет! Даже если переменная объявлена в начале функции, но без явной инициализации, в ней мусор:

void f() { int x; printf("%d ", x); // UB: x не инициализирован }

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


История

В банковском ПО пропущенная инициализация очередного счетчика внутри функции привела к тому, что иногда он был огромным отрицательным числом — результат: клиенту начислялись ошибочные бонусы, баг обнаружили только на реальных данных.


История

Мультимедийный обработчик изображений на старте предполагал, что статические массивы всегда заполнены нулями. После перехода на другой компилятор (с нестандартным окружением) обнаружили сегфолт — часть памяти не была физически отдана процессу.


История

В криптографической библиотеке разработчик не инициализировал временный буфер паролей, считая что буфер из global-секции заполнен нулями, но произошел случай с памятью, где остались старые чувствительные данные. Это привело к утечке паролей при дампе.