|
-342 / 1 / 0
Регистрация: 27.12.2025
Сообщений: 29
|
|
Неинициализированные указатели14.04.2026, 17:27. Показов 11603. Ответов 130
Метки нет (Все метки)
Подскажите пожалуйста, если использование неинициализированных указателей в С++ сопряжено с рисками неопределённого поведения и случайного доступа к памяти, то для каких целей в языке оставлена возможность объявления неинициализированных указателей?
0
|
|
| 14.04.2026, 17:27 | |
|
Ответы с готовыми решениями:
130
Неинициализированные локальные переменные Неинициализированные переменные Неинициализированные локальные переменные warning C4700 |
|
Вездепух
13235 / 6867 / 1827
Регистрация: 18.10.2014
Сообщений: 17,407
|
||
| 14.04.2026, 20:39 | ||
|
Вы задали вопрос о неопределенном поведении в С++. Это уже вопрос "для второго курса", то есть книгу Страуструпа здесь уже придется отложить в сторону (к плюшевым мишкам и пластмассовым вертолетикам) и браться за дело более серьезно.
0
|
||
|
-342 / 1 / 0
Регистрация: 27.12.2025
Сообщений: 29
|
|
| 14.04.2026, 21:03 [ТС] | |
|
Принимая за основу, что всё же создатель языка знает о чём пишет, рискну выразить своё видение вопроса.
При объявлении неинициализированного указателя ему рандомно присваивается адрес в памяти. Сделано это ради эффективности с целью "не производить те операции в которых нет необходимости" как отметил 000d60. На значение в памяти привязка указателя к нему сама по себе ни как не влияет (мы можем хоть 10 указателей привязать к одному адресу в памяти при желании). Из расчета, что пользователь знает что делает, C++ позволяет пользователю отстрелить себе ноги (записать по выделенному рандомно адресу новое значение затерев старое). При присваивании неинициализированному ранее указателю ссылки на нужное пользователю значение, как в примере Алексей 1153, происходит перезапись адреса указателя и проблема ссылки на выделенный ранее рандомно участок памяти перестаёт иметь место. Присваивание же разименнованному указателю, неинициализированному ранее, определенного значения "это всегда опасно" по определению - как отметил Алексей 1153, но "может быть безопасно" (если повезёт) как написал Страуструп если неинициализированный ранее указатель указывает на свободную (не занятую ни кем на момент объявления указателя) область памяти.
0
|
|
|
фрилансер
6510 / 5769 / 1135
Регистрация: 11.10.2019
Сообщений: 15,410
|
|||
| 14.04.2026, 21:06 | |||
|
Как раз неинициализированному указателю совсем-совсем ничего не присваивается - именно для эффективности. Чтобы не делать присваивание дважды
0
|
|||
|
Вездепух
13235 / 6867 / 1827
Регистрация: 18.10.2014
Сообщений: 17,407
|
||
| 14.04.2026, 21:18 | ||
|
1. Не имеет никакого значения, что там "присваивается" в неинициализированный указатель, так как язык С++ не даёт вам возможности увидеть это значение. 2. Вы рассуждаете в терминах времени выполнения ("создается", "присваивается") в то время как исходный вопрос ваш был про неопределённое поведение - концепция, которая проявляется в первую очередь во время компиляции. То есть то, что вы написали выше, не имеет никакого отношения к тому вопросу, который вы задали изначально. Вы уж определитесь, о чем ваш вопрос: о неопределенном поведении, или о том, что происходит с неинициализированной переменной во время выполнения.
1
|
||
|
-342 / 1 / 0
Регистрация: 27.12.2025
Сообщений: 29
|
|
| 14.04.2026, 21:47 [ТС] | |
|
Да нет, вопрос был для каких целей в языке оставлена возможность объявления неинициализированных указателей? Отсылка к рискам неопределенного поведения не заявлялась мной как цель вопроса. Я не знаю зачем вы мне битый час пытаетесь вдылдонить то, о чём я не спрашивал. Самый адекватный ответ как по мне был дан в самом начале пользователем 000d60 - "По тем же причинам что и другие типы данных. Ради эффективности. Не производить те операции в которых нет необходимости."
Цитата от ИИ "Если попытаться вывести значение неинициализированного указателя, например, с помощью std::cout, то на экран будет выведено адрес в памяти, который хранится в указателе. Это может быть любой адрес, включая тот, который не ссылается на допустимый объект."
0
|
|
|
Заблокирован
|
||
| 14.04.2026, 22:02 | ||
|
Именно этот нюанс как раз и показывает один из вариантов UB. (ИИ плохо ищут(угадывают) ответы на сложные вопросы) Что будет, никто не знает, а вероятные исходы такого обращения уже были приведены. При программировании на С++ стоит опираться только на стандарт - заявленное поведение. Именно для этого он и разработан. А UB - это цена низкоуровневых ЯП и их гибкости. И вообще, одна из проявлений природы вещей и их понимание человеком.
0
|
||
|
-342 / 1 / 0
Регистрация: 27.12.2025
Сообщений: 29
|
|
| 14.04.2026, 22:25 [ТС] | |
|
ИИ всего лишь выдал текст с одного из сайтов по программированию, не более того. Мнение человека, такого же как и мы с вами. У меня нет причин не доверять цитате ИИ, а уж заявление предыдущего оратора, что "Страуструп - врёт" вообще без комментариев.
0
|
|
|
Вездепух
13235 / 6867 / 1827
Регистрация: 18.10.2014
Сообщений: 17,407
|
||
| 14.04.2026, 22:30 | ||
|
ИИ вообще пока очень слабо разбираются в языках программирования, фактически просто цитируя то, что они нашли в интернете. Потенциала современного ИИ достаточно, чтобы освоить формальную систему, но пока что они предпочитают работать в режиме "поисковика".
0
|
||
|
Заблокирован
|
|||
| 14.04.2026, 22:33 | |||
|
Остальные ещё слабее. У него и правда много упрощений и вольных выражений, иногда даже противоречащие с другим его текстом в других книгах. На это нужно делать "скидку". Стандарт С++ это офф. руководство для создателей компиляторов и программистов. В компиляторах так же были и есть множество ошибок и несоответствий стандарту. А уж про UB, так любое поведение заложенное компилятором будет "нормальное", как решат его создатели. То есть, даже, если на некотором количестве ОС и откомпилированных программах наблюдается одно и то же поведение, но по стандарту это UB - это лишь проявление UB. Какие из этого следуют выводы? Писать код без UB.
0
|
|||
|
-342 / 1 / 0
Регистрация: 27.12.2025
Сообщений: 29
|
|
| 14.04.2026, 22:34 [ТС] | |
|
"Бред сивой кобылы?" Я вас умоляю, не смешите мои подковы. С такими аргументами мы далеко не уедем.
"Я его книгу читал только одну. У него и правда много упрощений и вольных выражений, иногда даже противоречащие с другим его текстом в других книгах." Как же вы это определили если читали только одну его книгу? Помоему тут врёт кто угодно только не Страуструп.
0
|
|
|
Вездепух
13235 / 6867 / 1827
Регистрация: 18.10.2014
Сообщений: 17,407
|
|||
| 14.04.2026, 22:36 | |||
|
0
|
|||
| 14.04.2026, 23:06 | ||
|
Не по теме: Такие глупые темы имеют неизменный успех :)
1
|
||
|
3146 / 1746 / 275
Регистрация: 19.02.2010
Сообщений: 4,557
|
||
| 14.04.2026, 23:17 | ||
|
Ибо КАДР в стеке функции под СРАЗУ ВСЕ объявленные локальные переменные выделяется ОДНОЙ (на архитектуре х86/х64) ассемблерной командой изменения значения процессорного регистра esp/rsp. Т.е. значения, оказавшиеся на вершине стековой памяти при входе в функцию, и становятся значениями у всех одновременно создаваемых лок.переменных. Далее компилятор в том или ином порядке отработает инициализирующие операторы для тех переменных, где таковые инициализации есть. Если же компилятор видит, что ему хватает процессорных регистров для размещения каких-то (или всех) лок.переменных в регистрах - то значением неинициализированной переменной будет значение регистра, отведённого для этой переменной. Под статически (на стеке) создаваемые объекты (экземпляры классов) - память выделяется тоже сразу со всеми прочими лок.переменными, но компилятор затем автоматически вызывает объектам их конструкторы (в данном случае - конструкторы по умолчанию, т.е. с пустым списком аргументов). Тут поле/поля класса останется/останутся неининициализированными в случае, если в тушке конструктора кодер забил болт на эту работу. Но во всех случаях - неинициализированной переменной ничего напрямую не присваивается. Что лежало в памяти (или в регистре) - то и станет значением неинициализированной переменной. В Си - всё полностью аналогично вышесказанному, за исключением того, что в Си нет классов и их конструкторов.
0
|
||
|
Вездепух
13235 / 6867 / 1827
Регистрация: 18.10.2014
Сообщений: 17,407
|
|||
| 14.04.2026, 23:28 | |||
|
Не по теме: Такие темы возникают с завидной периодичностью в одном и том же формате: очередной свезарегистрированный участник решает донести до общественности "своё, единственно правильное, видение языка С++", которое, вопреки заветам Страуструпа, извратили мракобесы из Комитета по Стандартизации. Традиционно подобные затеи выбрасываются в форум в виде некоего "вопроса", но на самом деле у аффтора вопросов нет: он пришел вещать, а не спрашивать. Детектируются подобные деятели довольно быстро: усваивать то, что им пытаются объяснить участники форума, они не хотят. Добавлено через 6 минут
0
|
|||
|
-342 / 1 / 0
Регистрация: 27.12.2025
Сообщений: 29
|
|
| 14.04.2026, 23:45 [ТС] | |
|
Так объяснить или вдылдонить? Вы бы определились.
А ник зарегистрирован ещё в прошлом году, если что. TheCalligrapher,
0
|
|
| 14.04.2026, 23:48 | |||
|
Не по теме:
0
|
|||
|
Заблокирован
|
||
| 15.04.2026, 00:13 | ||
|
Я даже ссылки нашел в стандарте где получим либо UB, либо EB(что ничем не лучше). Почему либо, потому что именно для конкретно приведенного случая ТС c указателем и вывод его адреса через std::cout, нужно копать глубже. Но по видимому зря старался. ТС не желает ничего слышать. А Страуструп пишет довольно однозначно про UB в коде(последний абзац) [скриншот прикреплен]. Единственная версия издания что есть под рукой у меня. "Бьерн Страуструп Язык программирования C++ Специальное издание" Но если всё же кому интересно, раздел : https://eel.is/c++draft/basic.indet
0
|
||
|
639 / 397 / 68
Регистрация: 09.03.2016
Сообщений: 4,376
|
||
| 15.04.2026, 00:41 | ||
|
Зачем тогда язык си? Я умный, или они умные? Кто программу пишет? Я по крайней мере должен сам планировать, когда что освободить. Какие такие умные? Читал кучу статей, где очень беспокояться, как бы я себе чего не отстрелил, и предлагают аж C++CLI. Хочешь что бы всё было умное, пиши на других ЯП.
0
|
||
|
Вездепух
13235 / 6867 / 1827
Регистрация: 18.10.2014
Сообщений: 17,407
|
||
| 15.04.2026, 00:43 | ||
esp. В большинстве функций "повседневной" сложности на современной платформе "почти все" скалярные переменные лягут в регистры.)Краткая история эволюции темы доступа к неинициализированным переменным в С выглядит так: * "Классический" С - C89/90 В первом стандартном С все было просто: чтение любой неинициализированной переменной - сразу неопределенное поведение. Точка. (В частности, например, нельзя читать даже неинициализированную переменную типа unsigned char.)* С99 Вышеописанный подход С89/90 быстро признали слишком педантичным-абстрактным-ограничивающим. В языке С часто приходится работать с неинициализированной "сырой" памятью через тип unsigned char. Наказывать пользователя за каждое чтение такой памяти неопределенным поведением было признанно неоправданно драконовской и ограничивающей мерой.По этой причине спецификацию переформулировали следующим образом: неинициализированные переменные содержат непредсказуемые внутренние (побитовые) представления. При этом переменные некоторых типов могут поддерживать особые внутренние представления - trap representations. Trap representation не задает никакого валидного значения для переменной. Попытка прочитать переменную с trap representation внутри сразу приводит к неопределенному поведению. Если тип поддерживает trap representations, то неинициализированная переменная такого типа запросто может "случайно" содержать trap representation, то есть чтение такой переменной в общем случае приводит к неопределенному поведению. Таком образом, для тех типов, которые поддерживают trap representations, фактически ничего не поменялось - читать неинициализированные переменные таких типов нельзя, ибо в общем случае вы будете нарываться на trap representations. А неинициализированные переменные тех типов, которые не поддерживают trap representations, можно читать совершенно спокойно: при чтении вы просто будете видеть какое-то непредсказуемое, но валидное значение. При этом про тип unsigned char в стандарте было открытым текстом заявлено - этот тип не имеет trap representations. Таким образом, неинициализированную переменную типа unsigned char можно читать совершенно спокойно.* C11 Казалось бы, все теперь хорошо. Но нет. Оказывается, что на платформах, поддерживающих спекулятивное выполнение кода (например, Itanium) регистры процессора могут находиться в особом состоянии - NaT (Not-a-Thing) - и чтение регистров, находящихся в таком состоянии, приводит к прерыванию выполнения программы. (Это, как несложно догадаться, хороший пример trap representation из реальной жизни). При этом на современных платформах большинство скалярных локальных переменных помещаются в регистры процессора. Получается, что если на такой платформе компилятор решил поместить обычную неинициализированную локальную переменную типа unsigned char в регистр процессора, компилятору придется еще предпринять усилия для того, чтобы сразу же сбросить в этом регистре состояние NaT. То есть на таких платформах компилятор фактически будет вынужден насильно инициализировать каждую неинициализированную локальную переменную типа unsigned char (так как стандарт говорит, что unsigned char не имеет trap representations.)Это неприемлемо в языке С. По ряду языковых причин объявление неинициализированной переменной в С не должно/не может порождать выполняемого кода (кроме объявления VLA). То есть для поддержки платформ с NaT в регистрах нужно было снова что-то менять. Было принято следующее решение, являющееся гибридом из подхода C89/90 и подхода C11: * Если переменная потенциально может быть размещена в регистре (то есть к ней нигде не применяется оператор взятия адреса &), то применяется подход из C89/90 - чтение такой неинициализированной переменной - сразу неопределенное поведение.* Если же переменная не может быть размещена в регистре (т.е. где-то к ней применяется оператор взятия адреса &), то применяется подход из C99 - переменную можно читать, но не забывайте о риске нарваться на trap representation.Это правило в стандарте языка сформулировано не через упоминание оператора &, а через ключевое слово register: если переменную можно объявить с классом памяти register, то работает "строгий" подход C89/90, а если нельзя - то работает "расслабленный" подход C99.Именно это правло, записанное в "6.3.2.1 Lvalues, arrays, and function designators" (C11) и известно в узких кругах как "Itanium clause": 2 [...] If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.
7
|
||
|
639 / 397 / 68
Регистрация: 09.03.2016
Сообщений: 4,376
|
|
| 15.04.2026, 00:49 | |
|
Две тыщи строк жуткого мусора.
И что, я года за три не стрелял ни в какие ноги? Конечно стрелял... И что? Это так ужасно... Исправил и всё...
0
|
|
| 15.04.2026, 00:49 | |
|
Ошибка, указывающая на неинициализированные переменные Ошибка: неинициализированные переменные Неинициализированные переменные
Указатели и указатели на указатели, а также типы данных Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
После закрытия оутлука продолжает висеть процесс в диспетчере задач
Maks 27.10.2026
С недавнего времени в продакшене возникла проблема: при закрытии оутлука в диспетчере задач продолжал висеть процесс outlook. exe. Проблема возникла после установки MS Office 2021 LTSC на машинах, под. . .
|
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него.
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952
Инструкция внутри.
https:/ / youtu. be/ VpfFZSUDGnQ. . .
|
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности.
Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
|
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version
Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
|
|
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер
На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
|
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/
TL DR
Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
|
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык.
Возвращает он вот это:
https:/ / i. **********/ vqBWLe2. png
Нужную строчку в 3й колонке просто выдумал. .
Это. . .
|
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor.
Это. . .
|