Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Не обнуляется переменная


Автор: Rexar 25.4.2008, 20:53
procedure perem;
var
  i: integer;
begin
  ShowMessage(IntToStr(i));
end;


Выводит какое-то значение ! Т.е. создаётся непустая переменная. Кто знает почему, и как с эти бороться !

P.s. - обнулять по типу i := 0 тупо и неразумно; А если у меня ТИП данных, где 100 таких переменных, мне что их все по очереди обнулять ? Проверял на Delphi 7 и Delphi 2005 !

Может надо где-то что-то прописать чтобы заработало ?

Автор: volvo877 25.4.2008, 21:05
Цитата(Rexar @  25.4.2008,  19:53 Найти цитируемый пост)
Кто знает почему, и как с эти бороться !

Встречный вопрос: а с чего ты решил, что она ДОЛЖНА обнуляться? Обнуляются глобальные переменные, а у тебя локальная, в стеке, там будет мусор...

Автор: Qu1nt 25.4.2008, 21:05
Вот такие они, локальные переменные, RTFM.
Цитата

А если у меня ТИП данных, где 100 таких переменных, мне что их все по очереди обнулять ?

FillChar.

Автор: Rexar 25.4.2008, 21:10
Код

Type
  TDataSpec = record
    Avtive, PageControl, Count, ... тут штук 100 подобных переменных ..., Promo, Version: integer;
    Client: TClientArray;
  end;

vat
  Data: TSpecData;


И как тут быть ? 

Автор: volvo877 25.4.2008, 21:17
Опиши не как Record, а как Class, поля класса при его создании обнулятся...

Автор: Qu1nt 25.4.2008, 21:21
Либо:
Код

FillChar(Data, SizeOf(TDataSpec), 0);

Автор: Rexar 25.4.2008, 21:45
Код
FillChar(Data, SizeOf(TDataSpec), 0);


А если запись будет содержать вложенные записи, то тоже будет работать ?


В данном примере вызов процедуры FillChar проинициализирует строки пустыми значениями, такой подход был нормальным в ранних версиях Delphi и Borland Pascal, но недопустим в последних версиях, в которых тип string по умолчанию соответствует типу LongString и суть указатель. Если значения строк перед инициализацией были не пусты, то мы получим утечку памяти.

Как вы это прокомментируете ?

Автор: aktuba 26.4.2008, 04:09
Цитата(Rexar @  25.4.2008,  22:45 Найти цитируемый пост)
Как вы это прокомментируете ?

Что тут комментировать то? Компилятор не может предсказать все твои действия, а если самому лень или не хватает ума - это твои проблемы. Надоедает, когда пишут такой бред, ощущение, что в программисты идут с мыслью, что стоит только компилятору сказать, что тебе надо - все будет готово.

Автор: Rexar 26.4.2008, 15:53
Цитата

Что тут комментировать то? Компилятор не может предсказать все твои действия, а если самому лень или не хватает ума - это твои проблемы. Надоедает, когда пишут такой бред, ощущение, что в программисты идут с мыслью, что стоит только компилятору сказать, что тебе надо - все будет готово.

Во первых я - металлург ! И не надо возгласов "Оно и видно" !
И вобще-то я ищу рациональное решение ! И я предположил, что возможно в компиляторе это настраивается, т.к. по сути обнуление переменных надо далеко не всегда необходимо и поэтому обнуление всех переменных будет уменьшать скорость работы программы, поэтому я думаю что  создатели делфи и не сделали обнуление включенным параметром !

И вобще я просил прокомментировать предыдущую цитату, т.к. я не совсем ясно понимаю её смысл ! Как именно я получу утечку памяти ?

Автор: volvo877 26.4.2008, 16:09
Цитата(Rexar @  26.4.2008,  14:53 Найти цитируемый пост)
Во первых я - металлург !
Это не повод для того, чтобы читать ответы, данные тебе ВЫБОРОЧНО... Вариант с классами тебя чем не устроил, можно полюбопытствовать?

Цитата(Rexar @  26.4.2008,  14:53 Найти цитируемый пост)
И вобще я просил прокомментировать предыдущую цитату
Ну, возможно, ты и знаешь, что это цитата, но здесь, прости, не форум телепатов. Если хочешь, чтоб об этом узнали и другие, можно было выделить цитату специальным тегом (хинт, посмотри слева от редактора есть такие круглые кнопочки, что на верхней написано?), и дать ссылку, ОТКУДА эта цитата выдрана.

Автор: aktuba 26.4.2008, 16:48
Цитата(Rexar @  26.4.2008,  16:53 Найти цитируемый пост)
Как именно я получу утечку памяти ?

Очень просто. Ты обнулишь указатели на строки, но сами строки останутся висеть в памяти.

Вообще, хорошая традиция, всегда в ручную обнулять переменные.

Автор: Rexar 26.4.2008, 20:23
Цитата
Очень просто. Ты обнулишь указатели на строки, но сами строки останутся висеть в памяти.

Т.е. будет постоянно увеличиваться потребляемая программой память ?

Цитата
Ну, возможно, ты и знаешь, что это цитата, но здесь, прости, не форум телепатов.

Ок, учту !

Код

  { 1.1: Полученные данные HTTP протокола: Request }
  TReadProtocolRequest = record
    Method: string;           // Комманда запроса
    URI: string;              // Строка запроса
    ProtocolType: string;     // Тип протокола
    ProtocolVersion: string;  // Версия протокола
  end;

  { 1.2: Полученные данные HTTP протокола: Header }
  TReadProtocolHeader = record
    ContentType: string;      // Тип передаваемых данных
    ContentLength: integer;   // Количество байт в "Body"
  end;

  { 1.X: Полученные данные HTTP протокола: все данные }
  TReadProtocolData = record
    Request: string;  // Строка запроса
    Header: string;   // Параметры запроса
    Body: string;     // Дополнительные данные
  end;

  { 1 Полученные данные HTTP протокола }
  TReadProtocol = record
    Request: TReadProtocolRequest; // Строка запроса
    Header: TReadProtocolHeader;   // Параметры запроса
    Data: TReadProtocolData;       // Все данные
  end;

  { 2: Отправленные данные HTTP протокола }
  TSendProtocol = record
    Data: TStream;
    IdStreamVCL : TIdStreamVCL;
  end;

  { Данные HTTP протокола }
  TProtocol = class(TObject)
    Read: TReadProtocol;  // Полученные данные
    Send: TSendProtocol;  // Отправленные данные
    Code: integer;        // Код результата
  end;


Т.е. при создании класса TProtocol будут обнуляться переменные во всех record, которые описаны в этом классе ?

Автор: VICTAR 26.4.2008, 20:33
Вообще, если речь идет конкретно о строках
Цитата

Процедура Initialize( var V [ ; Count: Integer] );

Модуль: System

Описание
Процедура инициализирует динамическую переменную.
Если динамическая переменная была создана не с помощью процедуры New, а другим способом (например, с помощью процедуры GetMem или процедуры ReallocMem), то после создания переменной, ее необходимо инициализировать процедурой Initialize. При вызове данная процедура обнуляет память, занятую длинными строками Variant-значениями и интерфейсами. Длинным строкам присваивается пустое значение, а для Variant-значений и интерфейсов устанавливается неопределенный тип (Unassigned). Необязательный параметр Count может быть определен, когда память под несколько переменных выделена в непрерывном адресном пространстве. Это позволяет инициализировать все переменные одним вызовом процедуры. Если переменная, определенная в параметре V не содержит длинных строк, Variant-значений и интерфейсов, то компилятор игнорирует данный вызов процедуры и не генерирует ни какого кода.

Автор: Rexar 27.4.2008, 02:23
Цитата

Цитата

Как именно я получу утечку памяти ?

Очень просто. Ты обнулишь указатели на строки, но сами строки останутся висеть в памяти.

А если я обнуляю внутри функции, то при выходе из функции строки уберуться из памяти ?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)