Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с TFileStream


Страницы:   1 2 3 4 5

ProgRAMmer Dimonych ©   (2007-11-05 22:45:00) 

Сталкивался много раз, сейчас решил разобраться :)

Дело в том, что TFileStream как-то странно себя ведёт. Даже, я бы сказал, непредсказуемо, т.е. не так, как должен был бы.

Например, в программе, которую я пишу сейчас используется вспомогательный модуль, содержащий объект для работы с файлами определённого формата. В некоторых его методах используется локальный

Tmp:TFileStream;

Забавно то, что в начале процедуры этот самый Tmp показывается (в Delphi'овом Hint'е) со свойством (Handle:12) и таким же остаётся после вызова его метода Free. То же самое с FileStream'ом, который блокирует файл до тех пор, пока он нужен моему объекту, и который объявлен как поле объекта.

Самое печальное, что, похоже, именно из-за такого поведения возникают AV и External Errors. Посмотрел исходник TFileStream'а и справку по Дельфям: в деструкторе TFileStream'а вызывается функция FileClose, которая, если верить справке, просто принимает Handle файла, что, на мой взгляд, имеет печальные последствия:

destructor TFileStream.Destroy;
begin
 if FHandle >= 0 then FileClose(FHandle);
 inherited Destroy;
end;


Т.е. FHandle передаётся не как var-параметр, а inherited Destroyтянется аж от TObject, где он virtual.

Попробовал копнуть в сети, но русскоязычного ничего не нашёл. Насколько мне позволяет судить моё знание английского, что-то по этой проблеме есть здесь: http://www.delphipraxis.net/topic77280.html.Если я правильно понимаю немецкий, то вместо метода Free следует юзать процедуру FreeAndNil().

Это так?


Юрий Зотов   (2007-11-06 01:45:00) [41]

> korneley ©   (06.11.07 01:38) [48]

А что тут странного или плохого? У меня, скажем, нет абсолютно никаких способностей к рисованию - ну так я и в художники не лезу, и обиженным себя нисколько не чувствую. Люди все разные, кому-то быть художником, кому - программистом, кому - певцом. И ничего странного, и ничего плохого.


korneley   (2007-11-06 01:38:00) [42]


> Юрий Зотов ©   (06.11.07 01:14) [47]
Как занятно эволюционировала ветка... Начали с использования указателей на объекты, а закончили (?) рекомендациями кому и чем следует заниматься :) Да, всетаки "неблагодарное это занятие - бить красных..." (с)


Юрий Зотов   (2007-11-06 01:14:00) [43]

> ProgRAMmer Dimonych ©   (06.11.07 00:27) [38]
> Компилятор нагрузить этим делом.

> vpbar ©   (06.11.07 00:28) [39]
> Компилятор добавит нужную информацию.

Вы представляете себе, что это будет за компилятор? Сложность его? Скорость его? Надежность его?

И объект, хранящий адреса всех ссылок на себя - Вы представляете, насколько увеличится объем занимаемой им памяти? Понимаете, что память эту придется еще и постоянно перераспределять (количество ссылок ведь меняется)? Что это будут серьезные тормоза, что увеличится фрагментированность памяти?

И главное - а зачем ве это? Чтобы люди, не понимающие, что такое указатель, тоже могли программировать? А на фига? Планете нужны не только программисты.

На крайняк - пусть юзают интерфейсы, пусть пишут на джаве или под дотнетом. Программирование на уровне адресов - не для них.


korneley   (2007-11-06 01:10:00) [44]


> Ни что не мешает, кроме защищенного режима
Не, ну своей переменной типа TObject, я могу присвоить всё, что угодно (а потом удивляться результатам), не взирая ни на что, тем более на "защищенный режим".


Германн   (2007-11-06 01:06:00) [45]


> korneley ©   (06.11.07 00:49) [44]
>
>
> > Ндя, если присваивать переменной типа TObject число -
> это
> > точно ошибка в геноме.
> А что мешает? В сысле не генома, а присвоения? Что хотим,
>  то и храним в отведённых нам 32-х разрядах.

Ни что не мешает, кроме защищенного режима.


korneley   (2007-11-06 00:49:00) [46]


> Ндя, если присваивать переменной типа TObject число - это
> точно ошибка в геноме.
А что мешает? В сысле не генома, а присвоения? Что хотим, то и храним в отведённых нам 32-х разрядах. Хоть четыре восьмибитных символа. Если правила позволяют - значит можно. Или ни разу не использовали TString.Objects[i] := TObject(<целое число>);?


vpbar   (2007-11-06 00:39:00) [47]

>>korneley ©   (06.11.07 00:37) [42]
Ндя, если присваивать переменной типа TObject число - это точно ошибка в геноме.


korneley   (2007-11-06 00:37:00) [48]


> vpbar ©   (06.11.07 00:13) [33]

>  Добавить в объект указатель на список ссылок на переменные
Пусть даже имеется "внутренний", только для системы "ССП". Как отследить все перемещения/присвоения ссылок и отличить их, скажем, от арифметических операций? b := $01234567; это адрес или нет?

>А ведь их может быть и не одна, запросто
> Вот это некоторая проблема
:))) Некоторая... :))) И не единственная... :))) Кроме ошибки в коде... генетическом...


ProgRAMmer Dimonych   (2007-11-06 00:33:00) [49]

> vpbar ©   (06.11.07 00:31) [40]
> ЗЫ. Видимо пора спать, чтобы червь сомнений не мутил мой
> светлый разум. :)

Червь - не самое страшное. Вон троянцы тоже спали, а в это время троянский конь сработал. :)


vpbar   (2007-11-06 00:31:00) [50]

Юрий, я уже начинаю сомневатся в своей правоте :) Хотя и не привык слепо верить авторитетам. Просто не пойму, что тут фантастичного.
ЗЫ. Видимо пора спать, чтобы червь сомнений не мутил мой светлый разум. :)


vpbar   (2007-11-06 00:28:00) [51]

>>Юрий Зотов ©   (06.11.07 00:24) [36]
Гм. А как объект знает какого он типа? И какую виртуальную функцию надо вызывать?
Компилятор добавит нужную информацию.


ProgRAMmer Dimonych   (2007-11-06 00:27:00) [52]

> Юрий Зотов ©   (06.11.07 00:24) [36]
> Каким образом объект в своем конструкторе может узнать о
> том, что где-то там вообще существует какая-то переменная
> a?
>
> Тем более, узнать ее адрес.

> Юрий Зотов ©   (06.11.07 00:25) [37]
> > > vpbar ©   (06.11.07 00:13) [33]
> b:=a; // добавляем ссылку на b в ССП
> А это и тем более фантастика.

Компилятор нагрузить этим делом. Ну, в смысле этот, как его? Который про адреса переменных всё знает? Линковщик. :)


Юрий Зотов   (2007-11-06 00:25:00) [53]

> > vpbar ©   (06.11.07 00:13) [33]
b:=a; // добавляем ссылку на b в ССП
А это и тем более фантастика.


Юрий Зотов   (2007-11-06 00:24:00) [54]

> vpbar ©   (06.11.07 00:13) [33]

a:=TObject.Create; // в том числе добавляем ссылку на a в ССП

КАК?

Каким образом объект в своем конструкторе может узнать о том, что где-то там вообще существует какая-то переменная a?

Тем более, узнать ее адрес.


vpbar   (2007-11-06 00:16:00) [55]

>>ProgRAMmer Dimonych ©   (06.11.07 00:14) [34]
>В COM, кажется, так делается?
Ага. В делфи, тоже, но только для интерфейсов.


ProgRAMmer Dimonych   (2007-11-06 00:14:00) [56]

> Юрий Зотов ©   (06.11.07 00:03) [28]

Не беспокойтесь Вы так, общее представление у меня есть. Скорее всего, с толку сбило то, что обычно не пользуюсь вот такими межпроцедурными вещами типа FFile в этом случае. Т.е. обычно Tmp:=TStringList.Create; в начале процедуры и Tmp.Free; в конце - и всё классно. А тут чего-то просто не подумал.

> vpbar ©   (06.11.07 00:03) [29]
> Ну тогда ссылки считать, и не освобождать пока все ссылки
> не обнулятся.

В COM, кажется, так делается?

===

А вообще - всем спасибо, по моему вопросу - всё.


vpbar   (2007-11-06 00:13:00) [57]


> Юрий Зотов ©   (06.11.07 00:07) [30]
> А каким-таким волшебным образом в методе Free объекта можно
> узнать о том, что такая переменная вообще существует?
Передавать в free указатель на переменную.

>>А ведь их может быть и не одна, запросто.
Вот это некоторая проблема.
Как вариант. Добавить в объект указатель на список ссылок на переменные (далее ССП).
var a,b,c:TObject;
....
a:=TObject.Create; // в том числе добавляем ссылку на a в ССП
b:=a; // добавляем ссылку на b в ССП
....
c:=b; // добавляем ссылку на c в ССП
b:=nil ; // удаляем ссылку на b из ССП
c.free; // освобождаем и обнуляем все ссылки из ССП
//
Про многопоточность думать еще надо. Хотя тоже решаемо.


Германн   (2007-11-06 00:13:00) [58]


> Юрий Зотов ©   (06.11.07 00:03) [28]

А с телефонной книжкой разъяснение было интереснее :-)


korneley   (2007-11-06 00:10:00) [59]


> С объектом связть список. В который добавлять указатель
> на переменную при присваивании объекта.
"Догнать Савранского - это утопия..." (с) :)


Юрий Зотов   (2007-11-06 00:07:00) [60]

vpbar ©   (05.11.07 23:52) [25]

> Ничего сложного для разработчиков.

В самом деле? Тогда один простенький вопросик можно? А каким-таким волшебным образом в методе Free объекта можно узнать о том, что такая переменная вообще существует?

А ведь их может быть и не одна, запросто.


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо