|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
19.12.2016, 19:56 | #1 |
Регистрация: 15.03.2015
Сообщений: 5
|
Всегда ли обнуляется указатель?
Здравствуйте!
Есть такой код: Код:
|
19.12.2016, 20:13 | #2 |
Старожил
Регистрация: 15.02.2010
Сообщений: 15,709
|
Я бы даже сказал, что в большинстве случаев данный код выкинется. Т.к. старое значение не используется и сразу перезатирается.
|
19.12.2016, 20:29 | #3 |
Регистрация: 15.03.2015
Сообщений: 5
|
Хм, операция new может сгенерировать исключение. В этом случае переменная pVal не будет перезатёрта, а значит, если компилятор выкинет инициализацию нулём, то pVal будет содержать случайное значение. Следовательно попытка вызова delete в блоке catch может закончиться очень плохо ((
Таким образом, возможна ситуация, когда старое значение не перезатирается и используется. Компилятор это не учтёт и всё равно выкинет обнуление переменной?? |
19.12.2016, 20:56 | #4 |
Старожил
Регистрация: 15.02.2010
Сообщений: 15,709
|
Вы в катч попадаете, если у нью все плохо. Зачем там делит делать?
|
19.12.2016, 21:43 | #5 |
Регистрация: 15.03.2015
Сообщений: 5
|
Да, Вы правы, в данном конкретном случае delete внутри catch не нужен. Я написал его там просто для примера. Дело не в delete, дело в том, что старое значение переменной, которое, якобы не используется и будет выкинуто компилятором, на самом деле использоваться может.
Если компилятор не выбросит инициализацию указателя нулём, то вызов delete в блоке catch будет безопасен, а если выбросит, то delete будет применяться к неинициализированному указателю. Неужели компилятор это не учитывает? |
19.12.2016, 23:21 | #6 |
Участник клуба
Регистрация: 23.12.2010
Сообщений: 1,129
|
Компилятор может оптимизировать как угодно до тех пор, пока не меняется наблюдаемое поведение программы (as-if rule). У этого правила есть только пара исключений - компилятор может убирать некоторые вызовы конструктора копирования (copy elision), и некоторые выделения памяти (начиная с С++14).
В приведенном примере кода оптимизация очевидно влияет на наблюдаемое поведение: внутри обработчика catch мы можем увидеть неинициализированное значение, хотя в коде оно инициализируется. Следовательно, компилятор может убрать присваивание тогда и только тогда, когда он на 100% гарантирует, что вызов new не бросит эксепшн. Тобишь в реальной жизни практически никогда. |
19.12.2016, 23:25 | #7 |
Вредный кошак
Участник клуба
Регистрация: 14.10.2012
Сообщений: 1,159
|
|
20.12.2016, 00:14 | #8 | |
Старожил
Регистрация: 15.02.2010
Сообщений: 15,709
|
Цитата:
|
|
20.12.2016, 11:28 | #9 | |
Вредный кошак
Участник клуба
Регистрация: 14.10.2012
Сообщений: 1,159
|
Цитата:
Например, если я перегружу operator new так, чтобы он выбрасывал не bad_alloc, то компилятор не сможет переместить присваивание в секцию catch, также, как и не сможет удалить его. Хотя он способен инициализировать нулем переменную сразу, потому как, между объявлением и присваиванием больше ничего не делается с данной переменной. |
|
21.12.2016, 01:13 | #10 |
Регистрация: 15.03.2015
Сообщений: 5
|
Ясно, всем спасибо за помощь.
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Не обнуляется таймер почему-то... | FleXik | Общие вопросы Delphi | 5 | 13.04.2014 17:54 |
Обнуляется переменная | Leonid183 | Visual C++ | 0 | 27.10.2011 16:06 |
Обнуляется переменная | Hippie | Помощь студентам | 1 | 09.01.2010 20:22 |
Socket обнуляется переменнaя | KoBRaAndrey | Работа с сетью в Delphi | 4 | 06.01.2010 21:30 |
Всегда позади и всегда впереди в одном приложении | Legat | Win Api | 4 | 27.10.2007 15:48 |