如何从Delphi中的函数返回一个对象而不会导致访问冲突? [英] How do i return an object from a function in Delphi without causing Access Violation?

查看:144
本文介绍了如何从Delphi中的函数返回一个对象而不会导致访问冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个delphi函数返回一个TStringList,但是当我返回一个值并尝试使用它时,我得到一个访问冲突错误,即

  myStringList:= FuncStringList(); 
myStringList.Items.Count //< - 这导致访问冲突

//函数FuncStringList
函数FuncStringList:TStringList;
var
vStrList:TStringList;
begin

vStrList:= TStringList.Create;
...
//填写vStrList

结果:= vStrList
vStrList.Free; //< - 当我在这里释放时,此函数将导致AccessViolation
end;

如何返回TStringList并仍然在本地函数中释放?

解决方案

Smasher说,你不能释放它;调用返回对象的函数的代码负责销毁它。



顺便说一下,这是坏的代码设计,因为它使得对于谁分配和释放一个更好的方法是让调用者创建对象并将其传递给函数。这样,创建它的代码也可以释放它。这样的东西:

  var 
SL:TStringList;
begin
SL:= TStringList.Create;
try
ProcToFillStringList(SL);
//做一些填充列表
finally
SL.Free;
结束
结束

//注意我已经将参数设置为TStrings而不是TStringList。这允许
//传递TMemo.Lines或TListBox或TComboBox Items。
procedure ProcToFillStringList(const SList:TStrings);
//用SList.Add()
结束来填充列表的任何东西

现在没有什么混乱,创建对象的相同代码负责释放它。而代码,IMO,更清楚阅读和维护。


I have a delphi function that returns a TStringList, but when I return a value and try to use it I get a Access Violation Error i.e

myStringList := FuncStringList();
myStringList.Items.Count   // <-- This causes an access violation

// function FuncStringList
function FuncStringList:TStringList;
var
  vStrList:TStringList;
begin

  vStrList := TStringList.Create;
   ...
  // Fill the vStrList

  Result := vStrList 
  vStrList.Free;    //<- when i free here, this function will cause AccessViolation
end;

How can I return the TStringList and still free it in the local function?

解决方案

As Smasher said, you can't free it; the code calling the function that returns the object is responsible for destroying it.

This is bad code design, by the way, as it makes it confusing as to who allocates and frees. A much better way to do it would be to have the caller create the object and pass it in to the function. That way, the code that creates it also frees it. Something like this:

var
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    ProcToFillStringList(SL);
    //Do something with populated list
  finally
    SL.Free;
  end;
end;

// Note I've made the parameter a TStrings and not a TStringList. This allows
// passing a TMemo.Lines or a TListBox or TComboBox Items as well.
procedure ProcToFillStringList(const SList: TStrings);
  // Do whatever populates the list with SList.Add()
end;

Now there's no confusion over who does what - the same code that creates the object is responsible for freeing it. And the code, IMO, is much clearer to read and maintain.

这篇关于如何从Delphi中的函数返回一个对象而不会导致访问冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆