3 / 3 / 0
Регистрация: 03.06.2019
Сообщений: 64
|
||||||
1 | ||||||
Почему данный код валидный?02.01.2020, 22:47. Показов 2895. Ответов 27
Метки нет (Все метки)
Привет всем. Написал вот этот код на компиляторе clang новейшей версии:
Ctor Dtor Dtor [Program finished] Но никаких ошибок. В чем дело, ребята?
1
|
02.01.2020, 22:47 | |
Ответы с готовыми решениями:
27
Почему работает данный код? Как работает данный код? И почему не компилируется? Как работает данный код и почему такой вывод? Почему данный код игнорирует 1-ый символ и приходится первую букву дублировать? |
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
02.01.2020, 22:55 | 2 |
Сообщение было отмечено NuMeRiC_ как решение
Решение
если явно не инициализировать указатель чем то осмысленным,
тогда он будет содержать мусор. однако, на некоторых системах (например на линуксах) при старте процесса вся его стековая память зануляется. это делается из соображений безопасности. поэтому, даже неинициализированный указатель содержит нуль. в этом случае твой код может отработать без ошибок. однако, это не делает сам код валидным. он по прежнему некорректен. если комплировать visual studio - приложение упадёт с ошибкой.
0
|
199 / 155 / 45
Регистрация: 11.11.2019
Сообщений: 348
|
|
02.01.2020, 23:02 | 3 |
Не упадет, т.к. "The C++ language guarantees that delete p will do nothing if p is equal to NULL"
1
|
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
02.01.2020, 23:06 | 4 |
с чего ты взял, что неинициализированный указатель будет содержать ноль?
на самом деле ещё как падает. gcc https://rextester.com/EUF58920 cl https://rextester.com/OKWN18097
1
|
3 / 3 / 0
Регистрация: 03.06.2019
Сообщений: 64
|
|
02.01.2020, 23:07 [ТС] | 5 |
То есть при первом освобождении поинтер указывает на NULL, а значит второе его освобождение не приведет ни к чему, так?
0
|
85 / 34 / 20
Регистрация: 15.12.2019
Сообщений: 88
|
||||||
02.01.2020, 23:15 | 6 | |||||
Нет ошибок в обоих вариантах, если в описании класса инициализировать указатель как
А вариант ТСА у меня не крашится и отрабатывает в VS19. Мне тоже интересно было бы узнать, почему, инициализрованный нулем указатель можно удалять неограниченное число раз без ошибок, учитывая то, что после первой отработки деструктора, он уже может заполнятся мусором и следовательно критовать. Ведь мы же освобождаем память, занимаемую самим указателем, а никак не память, на которую ссылается указатель.
0
|
199 / 155 / 45
Регистрация: 11.11.2019
Сообщений: 348
|
|
02.01.2020, 23:21 | 7 |
У Вас конструктор ничего не делает с указателем data. Но в VS (возможно не всегда) неинициализированный указатель становится равным NULL. Поэтому прога в VS не падает. Но в любом случае это плохая практика.
поэтому hoggy здесь абсолютно прав
0
|
85 / 34 / 20
Регистрация: 15.12.2019
Сообщений: 88
|
|
02.01.2020, 23:30 | 8 |
А стоп я сам дурак. Мы же удаляем объект по заданному в указателе адресу, а не сам указатель. Надо спать идти
0
|
199 / 155 / 45
Регистрация: 11.11.2019
Сообщений: 348
|
|
02.01.2020, 23:35 | 9 |
NULL можно удалять сколько угодно потому что с++ гарантирует, что ничего страшного не будет
0
|
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
02.01.2020, 23:52 | 10 |
не может он заполняться мусором.
деструктор - это на самом деле самая обычная функция, в которой обычно прописывают процедуру освобождения ресурсов. но не более того. деструктор не уничтожает объект. после того, как деструктор уже отработал, объект никуда не девается. память, которую занимает объект, так же никуда не девается. и если твой объект хранит внутри себя нулевой указатель, то этот указатель так же никуда не денется, и по прежнему будет хранить ноль. можешь хоть 10 раз вызывать деструктор - никакого мусора там по волшебству не образуется. волшебство начинается когда освобождается память, которую когда-то занимал объект. только после этого память может быть перезаписана чем то иным. не раньше. для автоматических объектов (как в случае ТС) такое волшебство начинается, когда звершается область видимости имени объекта.
1
|
85 / 34 / 20
Регистрация: 15.12.2019
Сообщений: 88
|
|
03.01.2020, 00:12 | 11 |
0
|
Вездепух
12792 / 6669 / 1795
Регистрация: 18.10.2014
Сообщений: 16,882
|
|
03.01.2020, 01:17 | 12 |
Этот код порождает неопределенное поведение по целому ряду причин. Никто вам не обещал, что неопределенное поведение будет проявляться в виде каких-то "ошибок". Неопределенное поведение может проявлять себя как угодно или не проявлять вообще. Вопросов типа "в чем дело" про неопределенное поведение нет и быть не может.
Вот и все объяснение. С практической же точки зрения вам в данном случае просто случайно повезло. Мусор в вашем указателе случайно оказался нулем. Добавьте в функцию main парочку посторонних переменных и все накроется медным тазом.Ничего подобного ни на каких "линуксах" нет и никогда не было.
1
|
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
03.01.2020, 01:24 | 13 |
0
|
Вездепух
12792 / 6669 / 1795
Регистрация: 18.10.2014
Сообщений: 16,882
|
|
03.01.2020, 01:35 | 14 |
И? К чему здесь эти абсолютно ничего не значащие примеры?
http://coliru.stacked-crooked.... 3468843e46 Я просто ума не приложу, как можно из очевидно бессмысленного эксперимента сделать такой далеко идущий вывод про "при старте процесса вся его стековая память зануляется". Просто классическая диссертация Василия Ивановича наблюдается ("Вывод: у таракана уши располагаются на ногах").
0
|
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
03.01.2020, 01:39 | 15 |
эти примеры наглядно иллюстрируют,
что в некоторых случаях память содержит нули. а в некоторых - не содержит.
0
|
Вездепух
12792 / 6669 / 1795
Регистрация: 18.10.2014
Сообщений: 16,882
|
|
03.01.2020, 01:42 | 16 |
Ну то есть, вы обнаружили, что мусор в памяти - это мусор в памяти, то есть содержать он может что угодно, в том числе и нули.
Однако как из этого родилась чепуха про некие "зануления стековой памяти" - по-прежнему не ясно.
1
|
Комп_Оратор)
|
||||||
03.01.2020, 01:45 | 17 | |||||
Сообщение было отмечено NuMeRiC_ как решение
Решение
NuMeRiC_, в вашем вопросе два независимых подвопроса. Я убрал освобождение по непредсказуемому адресу и прэкспериментировал с пустым деструктором. Его вызов сам по себе безобиден. Потом я вспомнил, что при реинициализации при помощи placement new деструктор вызывают принудительно и циклы destructor/new(placementPtr) могут в одной области работать сколько угодно.
0
|
8972 / 4318 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
03.01.2020, 01:46 | 18 |
мне очевидно, что в случае с gcc память на стеке содержит нули.
ты наверное думаешь, что это случайность? Добавлено через 1 минуту в отличие от обычного мусора, в случае с gcc, нули - не случайность, Бро.
0
|
Вездепух
12792 / 6669 / 1795
Регистрация: 18.10.2014
Сообщений: 16,882
|
|
03.01.2020, 01:46 | 19 |
Я уже полностью опроверг ваше "очевидно" своим контрпримером. Нет, в случае с gcc память на стеке НЕ содержит нули.
0
|
Комп_Оратор)
|
|
03.01.2020, 01:50 | 20 |
Были бы дороговаты. Сообщество прокляло бы Линуса Торвальдса. Ещё раз прокляло бы.
0
|
03.01.2020, 01:50 | |
03.01.2020, 01:50 | |
Помогаю со студенческими работами здесь
20
Что делает данный код? Помогите упростить данный код Что означает данный код? Объясните, пожалуйста, данный код Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |