powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Почему в этом коде утечка памяти
8 сообщений из 8, страница 1 из 1
Почему в этом коде утечка памяти
    #39612080
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  IMyInterface = interface
    ['{5A60B950-BD11-4938-BFCD-DBBF78D28FB2}']

  end;

  TMyInterface = class(TInterfacedObject, IMyInterface);

  ITestInterface = interface
    ['{268CC8E9-B75C-4990-A08F-D38F42E11E9B}']
    procedure Reg(const I : IMyInterface);
  end;

  TTestInterface = class(TInterfacedObject, ITestInterface)
    procedure Reg(const I : IMyInterface);
  end;

procedure Run;
var I : ITestInterface;
begin
  I := TTestInterface.Create;
  I.Reg(TMyInterface.Create);
end;

{ TTestInterface }

procedure TTestInterface.Reg(const I: IMyInterface);
begin

end;

begin
  ReportMemoryLeaksOnShutdown := true;
  try
    Run;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.


Вопрос к знатокам: Почему в этом коде появляются утечки памяти. Delphi XE7. Глюк?
...
Рейтинг: 0 / 0
Почему в этом коде утечка памяти
    #39612086
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очевидно, что потому, что нигде не освобождается объект класса, который создается здесь:ziv-2014
Код: pascal
1.
I.Reg(TMyInterface.Create);
...
Рейтинг: 0 / 0
Почему в этом коде утечка памяти
    #39612088
ramir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Бажина компилятора...
Надо так писать:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
procedure Run;
var 
  I : ITestInterface;
  M: IMyInterface;
begin
  I := TTestInterface.Create;
  M := TMyInterface.Create;
  I.Reg(M);
end;
...
Рейтинг: 0 / 0
Почему в этом коде утечка памяти
    #39612111
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это не баг, скорее, неочевидная особенность.

Объект, реализующий интерфейс, автоудаляется в момент уменьшения счётчика ссылок с 1 до 0. Однако в примере счётчик ссылок вообще не будет равен 1 и, следовательно, не сможет сбросится с 1 до 0, т.е. объект не будет автоматически удалён. А счётчик не становится равен 1, ибо у свежесозданного объекта счётчик = 0, а const счётчик не трогает (т.е. остаётся 0).

Итого: надо через переменную (тогда счётчик тронется с 0 до 1 и позднее, соответственно, с 1 до 0), либо убрать const, либо и то и другое.
...
Рейтинг: 0 / 0
Почему в этом коде утечка памяти
    #39612155
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker,
А почему при const не очищается счетчик? Там же везде интерфейсы.
Без const все работает без утечек.
...
Рейтинг: 0 / 0
Почему в этом коде утечка памяти
    #39612170
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ziv-2014, а с чего бы счётчик должен меняться при const, если const именно это и делает: блокирует изменения в переменной?
...
Рейтинг: 0 / 0
Почему в этом коде утечка памяти
    #39612239
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) Константные параметры могут передаваться функции по значению или по ссылке, в зависимости от конкретного используемого компилятора.
2) Использование const позволяет компилятору оптимизировать код для структурированных и строковых параметров.
3) Директива const по параметру указывает, что процедура / функция не изменяет значение, указанное в этом параметре. Если процедура или функция захочет манипулировать любым константным параметром, сначала нужно скопировать это значение в локальную переменную. Это позволяет компилятору выполнять некоторые оптимизации по таким параметрам, особенно в области ссылочных типов, таких как строки и интерфейсы и т. д.
Конкретно по интерфейсам, поскольку параметр объявлен как const, невозможно, чтобы значение переданной ссылки интерфейса было изменено во время «жизненного цикла» параметра (поскольку компилятор отклонит любой код, который пытается изменить значение), таким образом, компилятор способен устранить вызовы AddRef () и Release (), которые в этой процедуре будут генерироваться другим способом как пролог и эпилог.
4) Смотрим что генерирует компилятор в asm под win32
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Test(const A: IInterface)

005CE2CC 55               push ebp
005CE2CD 8BEC             mov ebp,esp
005CE2CF 51               push ecx
005CE2D0 8945FC           mov [ebp-$04],eax

Test2(A: IInterface)

005CE2DC 55               push ebp
005CE2DD 8BEC             mov ebp,esp
005CE2DF 51               push ecx
005CE2E0 8945FC           mov [ebp-$04],eax
005CE2E3 8B45FC           mov eax,[ebp-$04]
005CE2E6 E89DF5E3FF       call @IntfAddRef
005CE2EB 33C0             xor eax,eax
005CE2ED 55               push ebp
005CE2EE 6814E35C00       push $005ce314
005CE2F3 64FF30           push dword ptr fs:[eax]
005CE2F6 648920           mov fs:[eax],esp



Поэтому передача интерфейсной через const может сыграть злую шутку, если вы будете рассчитывать, что при передаче ее в метод счетчик ссылок будет расти
...
Рейтинг: 0 / 0
Почему в этом коде утечка памяти
    #39612299
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker, X-Cite,
Спасибо за объяснения. Ошибку искал с утечкой памяти. В общем-то очень удобная штука.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Почему в этом коде утечка памяти
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]