| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Баг компилятора или (пример)? |
| Автор: sptim 24.3.2016, 21:15 | ||
| Добрый день! Обращаюсь к знатокам, сам пишу на Делфи только в рамках сопровождения старых проектов и тут намедни поймал очень удививший меня баг. Ниже я специально набросал микро-тест воспроизводящий эту ситуацию:
Параметры среды: Delphi7, оптимизации отключены, WinXP sp2 32bit. Причем, если заменить Int64 на Integer - ошибок не будет (!). Т.е. это какой-то косяк компилятора (работа со стеком при Int64 аргументах)? Пробовал в инете поискать - ничего не нагуглилось. Может я чего-то недопонимаю - тогда буду благодарен за объяснение. |
| Автор: dnek 25.3.2016, 10:27 | ||
Не знаю поможет или нет, но правильнее было бы написать
Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Bag-kompilyatora-ili-(primer)-id56f42f5aae201598208b4567#findElement_E7045_56f4e857ae2015cb77cd5e86_0 |
| Автор: kami 25.3.2016, 18:30 | ||||||
| Переменная, содержащая экземпляр класса - это уже указатель. Поэтому объявление абсолютно излишне. Таким образом вы декларируете "указатель на указатель". Сам Result в вашем коде содержит валидный указатель на область памяти, в которой должен содержаться указатель на экземпляр класса. Вот только компилятор не знает о том, что участок памяти, на который ссылается ваш указатель, нельзя модифицировать. Чтобы сказать ему об этом - необходимо явно зарезервировать область памяти, т.е. сделать
В противном случае возможны вот такие неочевидные казусы. При этом нельзя забывать правило: если что-то выделил/создал - не забудь его удалить! (антипод New - процедура Dispose). Повторюсь - в вашем случае объявление PTest1 излишне. Так стоит поступать при динамическом создании record-ов, но никак не экземпляров классов. Преобразуйте свой код так, чтобы он возвращал себя же (компилятор нормально переваривает указание типа класса внутри самого класса):
И не забудьте про высвобождение ресурсов:
|
| Автор: dnek 26.3.2016, 11:51 | ||
Проблема здесь заключается не в PTest1 и не в Result (с ним как раз все в порядке и выделять память под него не надо). В данном примере проблема в строке
Ведь Self - это неявный параметр метода и, как и для остальных параметров, память для него выделяется при обращении к методу, а высвобождается при выходе из него. Т.е. Вы возвращаете указатель на переменную, которая существует только в теле метода и, соответственно, после его выполнения по этому адресу уже ничего нет. Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Bag-kompilyatora-ili-(primer)-id56f42f5aae201598208b4567#findElement_E7045_56f64dacae2015e04ccd61e1_0 |