Версия для печати темы
Форум программистов _ Delphi - Система _ Переменная с каким-то значением
Автор: slavon-x86 25:04:2008, 17:22
Код
procedure perem;
var
i: integer;
begin
ShowMessage(IntToStr(i));
end;
Выводит какое-то значение ! Т.е. создаётся непустая переменная. Кто знает почему, и как с эти бороться !
P.s. - обнулять по типу i := 0 тупо и неразумно; А если у меня ТИП данных, где 100 таких переменных, мне что их все по очереди обнулять ? Проверял на Delphi 7 и Delphi 2005 !
Автор: sax_ol 25:04:2008, 17:45
Цитата(slavon-x86 @ 25:04:2008 - 19:22)

P.s. - обнулять по типу i := 0 тупо и неразумно;
Почему?
Цитата(slavon-x86 @ 25:04:2008 - 19:22)

А если у меня ТИП данных, где 100 таких переменных
Какой такой тип?
Автор: slavon-x86 25:04:2008, 18:06
Цитата
Какой такой тип?
Вот такой !
Код
Type
TDataSpec = record
Avtive, PageControl, Count, ... тут штук 100 подобных переменных ..., Promo, Version: integer;
Client: TClientArray;
end;
vat
Data: TSpecData;
Цитата
Почему?
Хм, много однако....
Автор: sax_ol 25:04:2008, 18:19
И что видно если так: ShowMessage(IntToStr(Data.Active));?
Автор: slavon-x86 25:04:2008, 18:25
Цитата
И что видно если так: ShowMessage(IntToStr(Data.Active));?
440006
Автор: sax_ol 26:04:2008, 06:10
Вы точно привели пример, или нет? Или вот киньте сюда тест, где такое есть, посмотрим.
Автор: slavon-x86 26:04:2008, 18:48
Нет, не точно. Я писал вот так:
Цитата
Memo1.Lines.Add(IntToStr(Data.Active));
Автор: Yason 26:04:2008, 19:58
slavon-x86
1. Сделай TDataSpec не record'ом, а классом, и в конструкторе инициализируй поля как хошь.
2. ZeroMemory(@data, sizeof(data))
Автор: slavon-x86 26:04:2008, 20:19
Первый способ меня устраивает, но я не знаю как это сделать !
Второй даёт утечку памяти в строках !
Автор: Yason 26:04:2008, 23:46
Цитата(slavon-x86 @ 27:04:2008 - 00:19)

Первый способ меня устраивает, но я не знаю как это сделать !
Кхм... Не знаешь -- читай. Матчасть правильно учить по
книжкам.
Цитата(slavon-x86 @ 27:04:2008 - 00:19)

Второй даёт утечку памяти в строках !
А по подробнее? В каких строках, при каком использовании, можно с кодом.
Автор: slavon-x86 27:04:2008, 10:22
Цитата
А по подробнее? В каких строках, при каком использовании, можно с кодом.
Вот сорс ZeroMemory:
Код
procedure ZeroMemory(p:pointer;i:integer);
xor ecx,ecx
call FillChar
ret
В данном примере вызов процедуры FillChar проинициализирует строки пустыми значениями, такой подход был нормальным в ранних версиях Delphi и Borland Pascal, но недопустим в последних версиях, в которых тип string по умолчанию соответствует типу LongString и суть указатель. Если значения строк перед инициализацией были не пусты, то мы получим утечку памяти.
Автор: slavon-x86 27:04:2008, 12:36
Хотя я провёл тестирование и незаметил утечки...
Код
type
Tzzz = record
s, s1, s2: string;
end;
var
Form1: TForm1;
counter: LongInt = 0;
implementation
uses Unit2;
{$R *.dfm}
procedure TestMemory;
var
protocol : Tzzz;
begin
randomize;
FillChar(protocol, SizeOf(protocol), 0);
protocol.s1 := IntToStr(random(999999));
protocol.s2 := IntToStr(random(999999));
if counter mod 1000 = 0 then Form1.Caption := IntToStr(counter);
inc(counter);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
repeat
TestMemory;
until 1 = 2;
end;
end.
Автор: Yason 27:04:2008, 13:57
Во-первых, AnsiString создаётся пустой.
Во-вторых, если строку нужно (пере)инициализировать заново, это делается безо всяких ZeroMemory:
Код
s := '';
Применение ZeroMemory ещё можно придумать при работе с PChar, но AnsiString всё делает самостоятельно.
slavon-x86 Утечки памяти нет только потому, что Вы сначала создаёте protocol (неинициализированный), потом его зачищаете FillChar'ом, и только потом присваиваете осмысленные значения. После чего процедура заканчивается, protocol удаляется из стека вместе со своими полями, и никакой памяти не теряется.
А попробуйте в другом порядке
Код
protocol.s1 := IntToStr(random(999999));
protocol.s2 := IntToStr(random(999999));
FillChar(protocol, SizeOf(protocol), 0);
или сделайте protocol глобальной переменной. Потом запустите Task Manager, и посмотрите на потребление памяти.
P.S. Очень советую на время экспериментов
repeat заменить на
for с каким-нибудь скромным пределом, порядка сотни тысяч.
Автор: Silver Wind 28:04:2008, 05:47
Как вариант, чтобы не инициализировать каждое поле в записи по отдельности объяви типизированную константу в духе:
Код
const
EmptyDataSpec: TDataSpec = (Avtive: 0; PageControl: 0; ...);
И используй в духе LocalDataSpec:=EmptyDataSpec;
Русская версия Invision Power Board (http://www.nulled.ws)
© Invision Power Services (http://www.nulled.ws)