这会导致内存泄漏吗?

时间:2011-02-26 10:25:26

标签: delphi memory-leaks oop

type
  TTest = class
    a: integer;
  end;
  TTest2 = class(TTest)
    b: integer;
  end;

  var c:TTest;

  begin
    c:=TTest2.Create();
    c.Free;
  end;

2 个答案:

答案 0 :(得分:8)

不,它不会。

基类类型的变量可用于从其子类实例化对象(它们是类型兼容的),但请注意,使用这样的变量,您将只能访问TTest成员,而不能访问TTest2成员。那意味着;你可以访问“a”,但不能访问“b”。

此外,如果您在TTest2.Creation执行期间遇到任何异常,Create将不会返回部分构建的对象。

但是,如果在TTest2.Create和c.Free调用之间有其他代码,则在这些代码中引发异常会导致内存泄漏;因为C.Free可能无法执行。在这种情况下,您应该使用try-finally块。

答案 1 :(得分:5)

不,这里没有内存泄漏。构造函数仅在成功时才返回新资源。如果构造函数成功您无法调用Free,则只能泄漏。由于在构造函数和对Free的调用之间没有做任何操作,因此不存在泄漏。

如果构造函数失败,那么:

  • 调用析构函数以释放任何资源。
  • 引发异常。
  • 构造函数未返回,因为异常更改了程序流。
  • 在您的示例中,对象变量c的分配不会发生。

请注意,您已接受的@vcldeveloper的答案在说明返回nil时不正确。引发的构造函数不会返回任何内容。

您应始终使用try / finally包装Create / Free对,如下所示:

obj := TMyClass.Create;
try
  obj.DoSomething;
finally
  obj.Free;
end;

分配后,您只需保护资源。因此,您可以在作业之后放置try

如果将try放在错误构造函数之前:

try
  obj := TMyClass.Create;
  obj.DoSomething;
finally
  obj.Free;
end;

如果构造函数失败,那么obj没有被分配,然后当Free运行时(并且它将由于finally!而运行),它会在未初始化的变量上调用,从而导致未定义的行为。< / p>