释放 TObjectList 时发生访问冲突
我有以下德尔福代码:
destructor TXX_XXXX.Destroy;
var
i: Integer;
begin
if Assigned(Allocations) then
begin
for i:=0 to (Allocations.Count - 1) do
begin
try
TXX_ALOC(Allocations.Items[i]).Free;
except on Ex:Exception do
begin
OutputDebugString(PChar('Exception Error Message '+ Ex.Message));
end;
end;
end;
// Above code works well - no exception
try
FreeAndNil(Allocations); {Exception Here}
except on E:Exception do
begin
OutputDebugString(PChar('Exception in xxxxxxxxx.pas'+E.Message));
end;
end;
end;
inherited;
end;
模块“Vcl50.bpl”中地址 4003AB4 处发生访问冲突。读取地址2980BFFC
我知道访问冲突通常是由于释放某些对象而导致的
- 之前已被释放,
- ,该对象在使用某些对象而未初始化
但是在我进行释放之前,我检查了分配已分配。如果我放弃异常处理,我的应用程序将抛出错误。 Allocations 是一个 TObjectList,如果它是一个数组 - 我会怀疑我没有为数组分配长度,但它是一个 TObjectList。
多谢!
I have the following Delphi code:
destructor TXX_XXXX.Destroy;
var
i: Integer;
begin
if Assigned(Allocations) then
begin
for i:=0 to (Allocations.Count - 1) do
begin
try
TXX_ALOC(Allocations.Items[i]).Free;
except on Ex:Exception do
begin
OutputDebugString(PChar('Exception Error Message '+ Ex.Message));
end;
end;
end;
// Above code works well - no exception
try
FreeAndNil(Allocations); {Exception Here}
except on E:Exception do
begin
OutputDebugString(PChar('Exception in xxxxxxxxx.pas'+E.Message));
end;
end;
end;
inherited;
end;
Access violation at address 4003AB4 in module 'Vcl50.bpl'. Read of address 2980BFFC
I know the access violation usually caused by
- free some object which has been freed before
- use some object without initialization
But here before I do the free, I checked Allocations is assigned. If I discard the exception handling, my application will throw a something is wrong error.
Allocations is a TObjectList, if it is an array - I will doubt I didn't assign a length to the array, but it is a TObjectList.
Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
TObjectList
通常负责销毁其内容。在这种情况下不要释放您的对象。这将导致释放TObjectList
时发生访问冲突,因为它会尝试再次释放所包含的对象。对象列表的这种行为可以在其构造函数中控制:
使用此属性来指定是否希望列表拥有其内容(意味着:当项目从列表中删除时,它会负责销毁该项目)列表或列表被销毁)或不。不带参数的构造函数(您可能使用过)将其设置为
true
。您可能只需要一个类似
TList
的列表,但用于存储对象。如果是这种情况,请像这样创建列表:但如果您想要自动销毁行为,则只需删除 for 循环即可。对象列表将销毁您的
TXX_ALOC
对象。A
TObjectList
usually takes care of destroying its content. Don't free your objects in this case. This will lead to an access violation when freeing theTObjectList
because it tries to free the contained objects again.This behavior of the object list can be controlled in its constructor:
Use this one to specify if you want the list to own its content (means: it takes care of destroying an item when it is removed from the list or the list is destroyed) or not. The constructor without parameter (which you probably used) sets this to
true
.You probably just want a list like
TList
but for storing objects. If that's the case then create your list like this:But if you want the auto-destruction behavior then just remove the for-loop. The object list will destroy your
TXX_ALOC
objects.一般来说,当清除列表时,您希望从头到尾循环,
但如果是 TObjectList ,如果列表拥有对象(默认情况下),您不应该在销毁容器之前释放它们,因为列表会为您执行此操作。在上面的代码中,如果列表拥有对象,则调用 Delete 也会释放该对象。
Generally, when clearing lists you want to loop from end to start ie
but in case of TObjectList, if the list owns objects (which it does by default) you shouldn't free them before destroying the container as the list will do it for you. In the code above, if the list owns the objects then calling Delete also frees the object.
有 2 个选项供您选择...
1) 如果您希望 Delphi 在从 ObjectList 中删除对象时自动释放对象,则创建 TObjectList 并将 aOwnsObjects 设置为 true。在你的析构函数中简单的 FreeAndNil 是 ObjectList 本身。然后,这将从列表中删除所有对象并自动释放它们。由于释放 ObjectList 将自动释放该列表中包含的对象,因此您的代码可能如下所示:
2) 创建 TObjectList 并将 aOwnsObjects 设置为 False,在这种情况下,您必须自己负责释放列表中的对象。您的代码可能如下所示:
There are 2 options for your ...
1) Create the TObjectList wiht the aOwnsObjects set to true if you want Delphi to automatically free the objects when they get removed from the ObjectList. And in your Destructor simple FreeAndNil the ObjectList itself. This will then remove all objects from the list and free them automatically. Since freeing the ObjectList will automatically free the objects contained in that list, Your code could then look like :
2) Create the TObjectList wiht the aOwnsObjects set to False, in which case you will have to take care of freeing the objects in the list yourself. Your code could then look something like this :