Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 自由TStringList对象中存在错误_Delphi_Tstringlist - Fatal编程技术网

Delphi 自由TStringList对象中存在错误

Delphi 自由TStringList对象中存在错误,delphi,tstringlist,Delphi,Tstringlist,当我在不使用FreeListObjects(l)的情况下使用l.OwnsObjects:=TRUE时,会发生错误 谁将释放此字符串列表的对象?您已经告诉字符串列表,它拥有其对象数组中的对象。在这种情况下,当您销毁列表时,它将自动调用所有这些值的Free,就像您的FreeListObjects代码所做的那样 但是那里没有任何对象您已获取了非对象的整数值,并键入强制将其转换为TObject。您不能对整数调用自由,但在任何代码调用自由时,它都不知道值的原始类型。当你输入cast时,你告诉编译器你知道你

当我在不使用FreeListObjects(l)的情况下使用
l.OwnsObjects:=TRUE
时,会发生错误


谁将释放此字符串列表的对象?

您已经告诉字符串列表,它拥有其
对象
数组中的对象。在这种情况下,当您销毁列表时,它将自动调用所有这些值的
Free
,就像您的
FreeListObjects
代码所做的那样

但是那里没有任何对象您已获取了非对象的
整数
值,并键入强制将其转换为
TObject
。您不能对
整数
调用
自由
,但在任何代码调用
自由
时,它都不知道值的原始类型。当你输入cast时,你告诉编译器你知道你在做什么,编译器相信你。如果你真的不知道自己在做什么,不要输入cast

您说在没有
FreeListObjects
的情况下会出现错误,但在
FreeListObjects
的情况下也会出现错误。问题是,您正在调用非对象的
Free
。无论您是在自己的代码中调用它,还是让库调用它,这都不重要


您可能已经花了一些时间使用C#。在这种语言中,整数被自动“装箱”成为真实对象。Win32 Delphi不是这样工作的。Delphi不进行装箱操作。

OwnsObjects的操作基本上与FreeObjects例程相同,但当StringList本身被释放时,它会在内部处理它

但在我看来,你的问题来自你的例子。当我运行这个程序时,我会遇到访问冲突,因为您保存的“对象”根本不是对象,它们是强制到ToObject插槽的整数


这只是一个猜测,但你只是学习德尔菲,在其他语言的背景下,“一切都是一个对象”?德尔福的情况并非如此。对象是许多数据类型中的一种,您不能对其他数据类型调用Free。

扩展Rob的答案:您试图释放与地址相关的内容:nil、0x00000001、0x00000002、0x00000003和0x00000004。由于那里没有有效的对象,因此会出现访问冲突(注意:对nil对象调用Free不会产生错误)。

问题在于,当您将OwnObjects设置为true时,列表将对其中的每个项目调用Free。但是,由于您只是将整数强制转换为TObject,而不是真正创建Integer类型的对象,因此无法调用此强制转换对象中的任何方法

解决问题的方法是创建如下类:

procedure FreeListObjects( l : TStrings);
var i : integer;
BEGIN
   FOR i :=  0 TO l.Count -1 DO BEGIN
       l.Objects[i].Free;
       l.Objects[i] := NIL;
   END;
end;



PROCEDURE StringListAdd;
VAR i : INTEGER; Code : LONGWORD;
BEGIN
   l := Classes.TstringLIST.CREATE;
   FOR i := 0 TO 4 DO BEGIN
       Code := i  ;
       l.AddObject('', TObject(code));
   END;
   Code := LONGWORD(l.Objects[2]);
   FreeListObjects(l);
   l.Free;
END;
若要将此类实例的项目放入列表,请替换:

TInteger = class
  value: integer;
  constructor Create(v: integer);
end;


其他人已经指出了您代码中的问题,所以我只添加一条信息。如果您只想在列表中存储整数,请使用my unit中的TGPINTGERLIST或TGpInt64List。免费,没有附加条件。

对不起,这是我第一次在stackoverflow,下次我的问题会更准确。 我认为l.addobject将在tstringlist中创建和添加对象。 l.addobject(“”,tobject(code))(其中l是tstringlist,code是longword) 是否造成内存泄漏? longword何时定位? 我总是可以得到代码:=Longword(L.objects[i]);
我正在类型转换的对象是什么?

我知道在Delphi中,您需要通过执行以下操作来释放每个对象

例如,如果对象属于以下类

   l.AddObject('', TInteger.Create(code));
那么这就是你要做的:

TheClass = Class(TObject)
public
thestr:String;
end;
过程FreeListObjects(l:TStrings);
varⅠ:整数;
开始
对于i:=0到l。计数-1开始

自由类(l.对象[i]);莫尼尔。。。你的问题是什么?你有什么错误信息?你知道,当一个全新的人,他不习惯我们的风格和惯例,来问一个问题,但它的格式不太正确或描述不够,我们应该欢迎他们,并帮助他们找到答案,而不是联合起来对付他们,让他们淹没在反对票和接近的请求中。“你们真可耻!”梅森——我不同意;人们要求OP提供更多信息。如果提供了这些信息,通常会看到一个问题很快被重新打开。要正确回答一个不完整的问题是非常困难的。@Marc:我没有看到任何不完整的问题。我打开了Delphi,粘贴了他的代码,添加了对StringListAdd的调用,点击Run,立即得到了一个异常。正如他最后几行所暗示的,问题在于释放对象。这里没有不完整的信息;仅仅是人们聚集在一个新手身上,他把一个问题说得很糟糕,这就给StackOverflow带来了负面的印象,尤其是Delphi社区。这就是错误的最好解释。将对象添加到对象列表时,它们确实需要是对象。在WIN32中,整数不是对象!(对于没有WIN32经验的.NET开发人员来说,这是一个常见的错误。)在Delphi for.NET中,这段代码实际上可能会工作!你问题中唯一的问题是它没有提到它使用的是什么语言。欢迎来到堆栈溢出。投票否决你的四个人反应过度。无论如何,正如已经解释过的,没有对象。你没有分配任何内存,所以没有泄漏。
AddObject
的文档是否说它将分配一个新对象?该列表存储您给它的值的副本。在您的例子中,该值是一个整数,尽管它希望该值是一个对象引用。(请注意,复制对象引用不会复制对象。)不需要仅为调用该类而强制转换到该类-所有析构函数通常都会沿着继承树向上移动到ToObject,如果它们不这样做,应用程序无论如何都会遇到麻烦
TheClass = Class(TObject)
public
thestr:String;
end;
procedure FreeListObjects( l : TStrings);
var i : integer;
BEGIN
   FOR i :=  0 TO l.Count -1 DO BEGIN
       TheClass(l.Objects[i]).Free;   <----
       l.Objects[i] := NIL;
   END;
end;