~~~~~~~~~~~~~~~~~~~~ Arc.Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~ 
Номер скриншота №:
✰ D485EB16B9762E170A1DD3B2AE7769EC__1677088380 ✰
Заголовок документа оригинал.:
✰ Uninitialized variable - Wikipedia ✰
Заголовок документа перевод.:
✰ Неинициализированная переменная — Википедия ✰
Снимок документа находящегося по адресу (URL):
✰ https://en.wikipedia.org/wiki/Uninitialized_variable ✰
Адрес хранения снимка оригинал (URL):
✰ https://arc.ask3.ru/arc/aa/d4/ec/d485eb16b9762e170a1dd3b2ae7769ec.html ✰
Адрес хранения снимка перевод (URL):
✰ https://arc.ask3.ru/arc/aa/d4/ec/d485eb16b9762e170a1dd3b2ae7769ec__translat.html ✰
Дата и время сохранения документа:
✰ 21.06.2024 09:00:58 (GMT+3, MSK) ✰
Дата и время изменения документа (по данным источника):
✰ 22 February 2023, at 20:53 (UTC). ✰ 

~~~~~~~~~~~~~~~~~~~~~~ Ask3.Ru ~~~~~~~~~~~~~~~~~~~~~~ 
Сервисы Ask3.ru: 
 Архив документов (Снимки документов, в формате HTML, PDF, PNG - подписанные ЭЦП, доказывающие существование документа в момент подписи. Перевод сохраненных документов на русский язык.)https://arc.ask3.ruОтветы на вопросы (Сервис ответов на вопросы, в основном, научной направленности)https://ask3.ru/answer2questionТоварный сопоставитель (Сервис сравнения и выбора товаров) ✰✰
✰ https://ask3.ru/product2collationПартнерыhttps://comrades.ask3.ru


Совет. Чтобы искать на странице, нажмите Ctrl+F или ⌘-F (для MacOS) и введите запрос в поле поиска.
Arc.Ask3.ru: далее начало оригинального документа

Неинициализированная переменная — Википедия Jump to content

Неинициализированная переменная

Из Википедии, бесплатной энциклопедии

В вычислениях неинициализированная переменная — это переменная , которая объявлена, но не имеет определенного известного значения перед ее использованием. Это будет иметь некоторую ценность, но не предсказуемую. По существу, это ошибка программирования и распространенный источник ошибок в программном обеспечении.

Пример языка C [ править ]

Начинающие программисты обычно полагают, что всем переменным при объявлении присваивается известное значение, например ноль. Хотя это справедливо для многих языков, но не для всех, поэтому существует вероятность ошибки. Такие языки, как C, используют пространство стека для переменных, а набор переменных, выделенных для подпрограммы, известен как кадр стека . Хотя компьютер выделяет необходимое количество места для кадра стека, обычно он делает это просто путем корректировки значения указателя стека и не переводит саму память в какое-либо новое состояние (обычно из соображений эффективности). Следовательно, любое содержимое этой памяти в данный момент будет отображаться как начальные значения переменных, занимающих эти адреса.

Вот простой пример на C:

недействительный   счетчик  (   недействительный   ) 
 { 
     int   k  ,   я  ; 
    
      для   (  я   знак равно   0  ;   я   <   10  ;   я  ++  ) 
     { 
         k   знак равно   k   +   1  ; 
      } 
    
     printf  (  "%d"  ,   k  ); 
  } 

Окончательное значение kявляется неопределенным. Ответ, что это должно быть 10, предполагает, что он начался с нуля, что может быть правдой, а может и не быть. Обратите внимание, что в примере переменная i инициализируется нулем в первом предложении for заявление.

Другим примером может быть работа со структурами . В приведенном ниже фрагменте кода у нас есть struct studentкоторый содержит некоторые переменные, описывающие информацию о студенте. Функция register_student происходит утечка содержимого памяти, поскольку не удается полностью инициализировать члены struct student new_student. Если присмотреться, то вначале age, semester и student_numberинициализируются. Но инициализация first_name и last_nameчлены не правы. Это связано с тем, что если длина first_name и last_name массивы символов имеют размер менее 16 байт, во время strcpy, [1] нам не удается полностью инициализировать все 16 байт памяти, зарезервированные для каждого из этих элементов. Следовательно, после memcpy()преобразование полученной структуры в output, [2] мы пропускаем часть памяти стека вызывающему объекту.

struct   Student   { 
     unsigned   int   age  ; 
      беззнаковый   int   семестр  ; 
      char   first_name  [  16  ]; 
      имя_фамилии   16  [  ]  ; 
      беззнаковый   int   Student_number  ; 
  }; 

  int   Register_student  (  struct   Student   *  output  ,   int   age  ,   char   *  first_name  ,   char   *  Last_name  ) 
 { 
     // Если какой-либо из этих указателей равен нулю, мы терпим неудачу. 
      if   (  !  вывод   ||   !  первое_имя   ||   !  последнее_имя  ) 
     { 
         printf  (  "Ошибка!  \n  "  ); 
          вернуть   -1  ; 
      } 

     // Мы проверяем, что длина строк меньше 16 байт (включая нулевой байт) 
     // во избежание переполнения 
     if   (  strlen  (  first_name  )   >   15   ||    strlen  (  Last_name  )   >   15  )   { 
       printf  (  "имя и фамилия не могут быть длиннее 16 символов!  \n  "  ); 
        вернуть   -1  ; 
      } 

     // Инициализация членов 
     struct   Student   new_student  ; 
      новый студент  .   возраст   =   возраст  ; 
      новый студент  .   семестр   =   1  ; 
      новый студент  .   номер_студента   =   get_new_номер_студента  (); 
    
      strcpy  (  новый_студент  .  первое_имя  ,   первое_имя  ); 
      strcpy  (  новый_студент  .  последнее_имя  ,   последнее_имя  ); 

      //копируем результат в вывод 
     memcpy  (  output  ,   &  new_student  ,   sizeof  (  struct   Student  )); 
      вернуть   0  ; 
  } 

В любом случае, даже если переменная неявно инициализируется значением по умолчанию , например 0, это обычно не правильное значение. Инициализировано не означает правильно, если значение установлено по умолчанию. (Однако инициализация по умолчанию значением 0 является правильной практикой для указателей и массивов указателей, поскольку она делает их недействительными до того, как они фактически будут инициализированы правильным значением.) В C переменные со статической продолжительностью хранения, которые не инициализируются явно, инициализируются как ноль (или ноль для указателей). [3]

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

Воздействие [ править ]

Неинициализированные переменные являются серьезными ошибками, поскольку их можно использовать для утечки произвольной памяти, перезаписи произвольной памяти или обеспечения выполнения кода, в зависимости от случая. При использовании программного обеспечения, использующего рандомизацию расположения адресного пространства (ASLR), часто требуется знать базовый адрес программного обеспечения в памяти. Использование неинициализированной переменной для того, чтобы заставить программное обеспечение утечь указатель из ее адресного пространства, можно использовать для обхода ASLR.

Использование в языках [ править ]

Неинициализированные переменные представляют собой особую проблему в таких языках, как ассемблер C и C++ , которые были разработаны для системного программирования . Разработка этих языков включала в себя философию проектирования, согласно которой конфликты между производительностью и безопасностью обычно разрешались в пользу производительности. Программисту было поручено осознавать такие опасные проблемы, как неинициализированные переменные.

В других языках переменные при создании часто инициализируются известными значениями. Примеры включают:

  • VHDL инициализирует все стандартные переменные специальным значением «U». Он используется при моделировании для отладки, чтобы дать пользователю знать, когда неважные начальные значения через многозначную логику влияют на выходные данные.
  • В Java нет неинициализированных переменных. Поля классов и объектов, не имеющих явного инициализатора, и элементы массивов автоматически инициализируются значением по умолчанию для их типа (false для логических значений, 0 для всех числовых типов, null для всех ссылочных типов). [4] Локальным переменным в Java необходимо обязательно назначить их перед обращением к ним, иначе это будет ошибка компиляции.
  • Python инициализирует локальные переменные NULL (в отличие от None) и поднимает UnboundLocalError когда к такой переменной осуществляется доступ до (повторной) инициализации допустимым значением.
  • D инициализирует все переменные, если это явно не указано программистом.

Даже в языках, где разрешены неинициализированные переменные, многие компиляторы будут пытаться идентифицировать использование неинициализированных переменных и сообщать об этом как об времени компиляции ошибках . Некоторые языки помогают решить эту задачу, предлагая конструкции для обработки инициализации переменных; например, в C# имеется особый вариант параметров подпрограмм, вызываемых по ссылке (задаваемых как out вместо обычного ref), утверждая, что переменную можно не инициализировать при вводе, но она будет инициализирована впоследствии.

См. также [ править ]

Ссылки [ править ]

  1. ^ стркпи
  2. ^ мемкпи()
  3. ^ «ISO/IEC 9899:TC3 (текущий стандарт C)» (PDF) . 07.09.2007. п. 126 . Проверено 26 сентября 2008 г. Раздел 6.7.8, пункт 10.
  4. ^ «Спецификация языка Java: 4.12.5 Начальные значения переменных» . Сан Микросистемс . Проверено 18 октября 2008 г.

Дальнейшее чтение [ править ]

Arc.Ask3.Ru: конец оригинального документа.
Arc.Ask3.Ru
Номер скриншота №: D485EB16B9762E170A1DD3B2AE7769EC__1677088380
URL1:https://en.wikipedia.org/wiki/Uninitialized_variable
Заголовок, (Title) документа по адресу, URL1:
Uninitialized variable - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть, любые претензии не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, денежную единицу можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)