Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> string поле в record, и указатель на record 
:(
    Опции темы
Seldon
Дата 12.11.2006, 03:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 114
Регистрация: 23.12.2005
Где: Minsk

Репутация: нет
Всего: 2



тут недавно обнаружил такую ситуацию:
Код

type
  TRec=record
    Str:String;
  end;
  PRec=^TRec;

var
  List:TList;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Dispose(List[0]);
  List.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Rec:PRec;
begin
  New(Rec);
  Rec^.Str:='123';
  List:=TList.Create;
  List.Add(rec);
end;

в результате имеем мемори лик (проверял FastMM4) - этот самый стринг '123'. если же написать
Код

Dispose(PRec(List[0]));

то всё ok. в общем-то вполне ожидаемое поведение smile но пока меня FastMM в него носом не ткнул я про него не знал. и появилась такая проблема: в проекте куча вот таких вот record'ов с полями string, указатели на котрые (на record'ы) храняцца в процессе работы в TList и в конце особождаюцца вот таким кодом:
Код

procedure FreeList(List:TList);
var
  a:Integer;
begin
  for a:=0 to List.Count-1 do
    Dispose(List[a]);
  List.Free;
end;

но получаецца что он неправилен. можно конечно написать для каждого типа record'a свою процедуру, но как-то это нерационально. может можно как-то передать в процедуру ссылку на тип (ну вроде class of только для типа) чтобы сделать приведение указателя к нему?

Это сообщение отредактировал(а) Seldon - 12.11.2006, 03:55
--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
digs
Дата 12.11.2006, 06:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 14.10.2006

Репутация: нет
Всего: 1



Я вижу три варинта:
1. Сделать вместо string везде string[255], но это ограничит размер строки
2. объявить все записи как class
3. Сделать в каждой записи первым поле, в которое будешь помещать код типа. Тогда просто пишешь вместо New и Dispose свои процедуры. New будет заполнять эти первые байты, а Dispose, анализировать их же и соответственно накладывать тип, чтобы корректно высводобить строки
PM MAIL   Вверх
Guedda
Дата 12.11.2006, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


Профиль
Группа: Завсегдатай
Сообщений: 3137
Регистрация: 27.12.2005
Где: Ростов-на-Дону

Репутация: 14
Всего: 78



Всегда нас в университете учили в records писать стринги инициализированные. так что лучше писать:
Код

  Str : string[255];



--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
Seldon
Дата 12.11.2006, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 114
Регистрация: 23.12.2005
Где: Minsk

Репутация: нет
Всего: 2



Цитата(digs @ 12.11.2006,  06:43)
Я вижу три варинта:
1. Сделать вместо string везде string[255], но это ограничит размер строки
2. объявить все записи как class
3. Сделать в каждой записи первым поле, в которое будешь помещать код типа. Тогда просто пишешь вместо New и Dispose свои процедуры. New будет заполнять эти первые байты, а Dispose, анализировать их же и соответственно накладывать тип, чтобы корректно высводобить строки

1. не катит smile
2. вот к этому я уже сам пришёл, по почему-то не нравицца мне это решение
3. интересно, спасибо за интересную идею

Цитата

Всегда нас в университете учили в records писать стринги инициализированные.
а вот кстати, почему в этом случае нет лика? как я понимаю в случае string, компилятор не знает о ней и освобождает только 4 байта, занимаемые указателем на строку, а количество ссылок на строку не уменьшаецца? так? а как в случае с string[255]?
--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
Alexeis
Дата 12.11.2006, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(Seldon @  12.11.2006,  03:53 Найти цитируемый пост)
в результате имеем мемори лик (проверял FastMM4) 

Это слишком подозрительно, работа с длинными строками в Delphi полностью автоматизирована, так что утечек памяти быть не должно, вероятно где-то еще имеется ссылки на эти строки. Как только число ссылок станет равным нулю память автоматически освободится. Не забывайте делфи многие операции оптимизирует дабы не грузить зря ни проц  ни память. То что память осталось не освобожденной еще не значит, что про нее совсем "забыли". Такой совет, при работе со строками не следите за их памятью, многие уже достаточно "издевались" тестируя их на утечки , но все безрезультатно, строки работают как часы!


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
digs
Дата 12.11.2006, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 14.10.2006

Репутация: нет
Всего: 1



Цитата(Seldon @  12.11.2006,  16:13 Найти цитируемый пост)
а вот кстати, почему в этом случае нет лика? как я понимаю в случае string, компилятор не знает о ней и освобождает только 4 байта, занимаемые указателем на строку, а количество ссылок на строку не уменьшаецца? так? а как в случае с string[255]?

В этом случае строка представлена как в паскале. Т.е. не ссылкой, а как есть. Какова длина строки, настолько (плюс один байт) у тебя увеличивается структура. 
При распределении нужно только длину в ноль установить. Хотя, если ты сразу забиваешьш значения, то не нужно

Это сообщение отредактировал(а) digs - 12.11.2006, 14:39
PM MAIL   Вверх
Seldon
Дата 12.11.2006, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 114
Регистрация: 23.12.2005
Где: Minsk

Репутация: нет
Всего: 2



Цитата(alexeis1 @  12.11.2006,  14:21 Найти цитируемый пост)
 вероятно где-то еще имеется ссылки на эти строки.
код в моём первом посте, созданная строка больше нигде не используецца.

Цитата(alexeis1 @  12.11.2006,  14:21 Найти цитируемый пост)
То что память осталось не освобожденной еще не значит, что про нее совсем "забыли".
ну я так думаю, что FastMM проверяет на лики в самом конце жизни приложения, когда сбощик мусора делфи уже сделал всё, что хотел. возможно проблема в самом FastMM - например родной менеджер памяти может быть при закрытии приложения освобождает все строки, независимо от количества ссылок на них.... фиг его знает  smile 

такой вопрос: в nt-based os каждое приложение имеет собственное адресное пространство и os после закрытия приложения всё равно вернёт себе всю занимавшуюся им память? т.е. лики просто увеличивают используемую во время работы приложения память? а после его завершения os всё себе вернёт?

Цитата(alexeis1 @  12.11.2006,  14:21 Найти цитируемый пост)
многие уже достаточно "издевались" тестируя их на утечки , но все безрезультатно, строки работают как часы!
может есть ссылки на материалы по этому?
--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
digs
Дата 12.11.2006, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 14.10.2006

Репутация: нет
Всего: 1



Я тут еще вспомнил про Object.
Можно его использовать, а не record.
Скорее всего для него информация о строках сохраняется, и Dispose для него будет скорее всего кореектно отрабатываться. 
PM MAIL   Вверх
Romikgy
Дата 12.11.2006, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



а че вместо своей структуры , не заюзать TStringList


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Seldon
Дата 12.11.2006, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 114
Регистрация: 23.12.2005
Где: Minsk

Репутация: нет
Всего: 2



Цитата(digs @  12.11.2006,  17:28 Найти цитируемый пост)
Я тут еще вспомнил про Object.Можно его использовать, а не record.
да, можно, но
1. мне это не нравицца по религиозным убуждениям.
2. хочу таки разобрацца с этим вопросом.

Цитата(Romikgy @  12.11.2006,  17:40 Найти цитируемый пост)
а че вместо своей структуры , не заюзать TStringList
потому что не все поля записи - string. например вот такая структура:
Код

  TFTPAccount=record
    Name,Server,Username,Password,InitDir:String;
    Port:Integer;
    Passv:Boolean;
    UseSocks:Boolean;
    SocksServer:String;
    SocksPort:Integer;
    SocksVersion:TSocksVersion;
    SocksAuth:Boolean;
    SocksUsername:String;
    SocksPassword:String;
  end;

её можно легко сделать классом, и проблема исчезнет, но public поля класса вида Port:Integer; мне будут резать глаза и я сделаю
Код

private
  fPort:Integer
public
  property Port:Integer read fPort write fPort;

а это много лишнего кода, который затрудняет чтение и понимание.
--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
Quadr0
Дата 12.11.2006, 20:27 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











...

Это сообщение отредактировал(а) Quadr0 - 15.7.2011, 13:22
  Вверх
Seldon
Дата 12.11.2006, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 114
Регистрация: 23.12.2005
Где: Minsk

Репутация: нет
Всего: 2



Цитата(Quadr0 @  12.11.2006,  20:27 Найти цитируемый пост)
Этой строкой ты ничего, собственно не освобождаешь. Dispose нужно передать типизированный указатель, чтобы этот метод знал сколько памяти нужно осводить.
мне кажецца, ты неправ. простой тест показывает, что, например, с Integer нет никаких проблем и они освобождаюцца нормально даже при передаче в Dispose нетипизированного указателя. проблемы только со String и, видимо, со всеми другими типами с управляемым временем жизни. кстати, какие, кроме String существуют ещё?

и по сути вопроса: какие предложения по поводу разрешения моей ситуации? (см. вторую половину первого поста). кроме замены record на class. пока что одно предложение:
Цитата

3. Сделать в каждой записи первым поле, в которое будешь помещать код типа. Тогда просто пишешь вместо New и Dispose свои процедуры. New будет заполнять эти первые байты, а Dispose, анализировать их же и соответственно накладывать тип, чтобы корректно высводобить строки

--------------------
MiBEditor v2.Alpha 10 - Программерский редактор
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0603 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.