![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| yours-tester |
|
|||
|
Unregistered |
Начал изучать C++ с помощью VC6++ на winXP
Не могу найти ответ на интересующий меня вопрос. Разобрал пример и он привёл меня в ступор. А правильно ли я выбрал язык на котором хочу кое-что написать? Что то какая то нелогичность получается в этом языке с указателями пример приведён ниже, если не перегружать оператор присваивания (закоментировать первый #define), то после команды Str3=Str2=Str1 Str1.s, Str2.s, Str3.s - указывают на одну и ту же строку но это ещё пол беды, когда после Str1.destroy() вызывается Str2.destroy() происходит ошибка приложения и Windows пытается отослать в Microsoft сообщение об ошибке. Оно понятно что, Str2.s уже указывает, на освобождённую память, но неужели оператор delete этого не может распознать и корректно отработать этот случай? Что за этим разве программист должен следить? Вот учебный пример
Это сообщение отредактировал(а) chipset - 6.2.2005, 20:14 |
|||
|
||||
| S.A.P. |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2664 Регистрация: 11.6.2004 Репутация: 9 Всего: 71 |
|
|||
|
||||
| srd |
|
|||
![]() Нереварин ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 951 Регистрация: 30.8.2003 Где: Владивосток Репутация: 27 Всего: 49 |
Ну и? Повторное освобождение уже освобождённой памяти является грубейшей ошибкой в любом языке программирования, поддерживающем работу с указателями, в том числе и в тех, которые имеют сборщик мусора (типа явы или си шарпа). Всё просто и логично.
Добавлено @ 15:18
Отладочная версия run-time может обнаруживать повторное освобождение памяти и выдавать исключение. Релизная версия будет молча ломать кучу, из-за чего баг будет вылазить совсем в другом месте. -------------------- Не смей читать мою подпись!!! |
|||
|
||||
| Domestic Cat |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5452 Регистрация: 3.5.2004 Где: Dallas, US Репутация: 3 Всего: 172 |
Не понял, как в менеджед языках можно повторно память освободить? -------------------- |
|||
|
||||
| chipset |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
Перегрузи функцию delete и заставь её проверять NULL ли обьект перед удалением, и обнулять его в противном случае.
Мы так делаем Добавлено @ 20:15 Так, на будущее... пользуйся плз тегами [code=cpp][/code], удобнее читать просто Это сообщение отредактировал(а) chipset - 6.2.2005, 20:15 --------------------
|
|||
|
||||
| En_t_end |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2074 Регистрация: 4.12.2004 Репутация: 1 Всего: 20 |
Вообще фигня полная !!!
Первый раз вижу такую тупую реализацию! |
|||
|
||||
| chipset |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 4071 Регистрация: 11.1.2003 Где: Seattle, US Репутация: 27 Всего: 165 |
En_t_end, насчёт стиля ничего плохого сказать не могу...
--------------------
|
|||
|
||||
| Конструктор |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 641 Регистрация: 12.5.2004 Где: Москва Репутация: нет Всего: 10 |
chipset, кажысь стандартная реализация и так проверяет не NULL-ли объект, тока сама в NULL не ставит при удалении. Вроде где то я читывал что по стандарту совершенно безопасно применить delete к NULL указателю
|
|||
|
||||
| yours-tester |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 56 Регистрация: 6.2.2005 Репутация: нет Всего: нет |
Вообще то здесь delete применяется не к NULL указателю, а к перекрёстному указателю, который не равен NULL, но указывает на уже освобождённую память.
Вопрос в том, есть ли способ узнать, что не NULL указатель указывает на освобождённую память. И не освобождать её вторично. Отладчик ведь откуда то об этом знает и покрасил мне переменные в красный цвет. А оператор delete почему не может узнать этого? |
|||
|
||||
| Конструктор |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 641 Регистрация: 12.5.2004 Где: Москва Репутация: нет Всего: 10 |
А зачем ему? Ему скорость важна, а если не важна то как и было замечено Java и C#
|
|||
|
||||
| gepard |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2477 Регистрация: 29.2.2004 Репутация: 2 Всего: 40 |
Конструктор
Ошибаешься... yours-tester
Значит - NULL. Указатель - это как человек, который указывает на область памяти пальцем. Он тычит и говорит: "Вот здесь". А раз он NULL, то он - 0...0 - это NULL, NULL - это 0... Если ты пишешь:
Это значит, что Человек с именем str3 тычет пальцем на область памяти, куда тычат str1 и str2. Если ты удалил эту область, то получается, что тыкать-то им некуда. str1.Destroy(); - парень с именем str1 перестаёт тыкать пальцем на область памяти. str2.Destroy(), str3.Destroy(); - str2 и str3 рады перестать тыкать, но они уже перестали и второй раз перестать не могут... -------------------- Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным! © Я, Берсерк, что значит - Неистовый. |
||||||
|
|||||||
| srd |
|
||||||||||
![]() Нереварин ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 951 Регистрация: 30.8.2003 Где: Владивосток Репутация: 27 Всего: 49 |
Ага, заврался я
А вот повторного освобождения я не добился, как ни пытался.
Да нет, с точки зрения стандарта применять delete к нулевому указателя безопасно.
-------------------- Не смей читать мою подпись!!! |
||||||||||
|
|||||||||||
| S.A.P. |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2664 Регистрация: 11.6.2004 Репутация: 9 Всего: 71 |
На сколько я знаю, не во всех реализациях языка NULL есть 0. Поэтому для указателей лучше все таки использовать NULL. Стандарт языка гарантирует, что по адресу NULL ничего не будет и все операции с ним абсолютно безопасны. А delete 0 может не прокатить. |
||||
|
|||||
| srd |
|
|||
![]() Нереварин ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 951 Регистрация: 30.8.2003 Где: Владивосток Репутация: 27 Всего: 49 |
Если мы говорим про Си++, то в стандарте есть понятие 0 как нулевого указателя, но нет ничего про NULL. Это просто наследине из Си-шной CRT. Более того, компилятор всегда может интерпретировать 0 как нулевой указатель, а вот NULL в разных реализациях может быть определён как 0, как (void *)0, как (long *)0 и т.п. Это может создать проблемы. Так что, что лучше - ещё вопрос.
-------------------- Не смей читать мою подпись!!! |
|||
|
||||
| gepard |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2477 Регистрация: 29.2.2004 Репутация: 2 Всего: 40 |
srd
Твоя правда... Но только в том случае, если указатель точно "0". Добавлено @ 14:54 Если delete вызывать после delete, то будет лаг... -------------------- Когда начинаются цифровые войны, а траффик разносит моё сознание по бесконечным просторам инета, подобно ветру, разносящему листву по полям, тогда и только тогда я чувствую себя свободным! © Я, Берсерк, что значит - Неистовый. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |