Delphi 访问冲突从 TStringsList 读取对象
收到以下
我在模块“test.exe”中的地址 00404340 处 读取地址 FFFFFFD5
使用以下代码
var
List: TStrings;
访问冲突。在创建部分中 :List:= TStringList.Create;
添加到列表:结果 := List.AddObject('hi', aCreatedObject);
MessageDlg(FunctionHookList.Objects[Result].ClassName, mtInformation, [mbOK], 0);
消息对话框显示正确的类名
但是稍后当我这样做时,
i := list.IndexOf('hi');
if i >= 0 then
if list.Objects[i] <> nil then
if assigned(list.Objects[i]) then
begin
tmp := list.Objects[i];
if tmp <> nil then
MessageDlg(tmp.ClassName, mtInformation, [mbOK], 0); //*******
end;
我在 < code>//******** 行
我知道那里有一些重复的代码,但我试图检查'所有内容'
Im getting the following
Access violation at address 00404340 in module 'test.exe'. Read of address FFFFFFD5
with the following code
var
List: TStrings;
In the Create Section:List:= TStringList.Create;
Adding to the list:Result := List.AddObject('hi', aCreatedObject);
MessageDlg(FunctionHookList.Objects[Result].ClassName, mtInformation, [mbOK], 0);
The Message dialog shows the correct classname
But later when i do,
i := list.IndexOf('hi');
if i >= 0 then
if list.Objects[i] <> nil then
if assigned(list.Objects[i]) then
begin
tmp := list.Objects[i];
if tmp <> nil then
MessageDlg(tmp.ClassName, mtInformation, [mbOK], 0); //*******
end;
i get the Access violation above at on the //*******
line
I know there is a bit of duplicated code there, but i was trying to check 'everything'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来您的程序正在从空指针的负偏移量读取。该偏移量与 VMT 中存储类名的偏移量相差 1,表明该对象存储其 VMT指针保存的是地址1,而不是其类的VMT的实际地址。
这就让人怀疑您是否真的在该列表中存储了有效的对象引用。您正在向
List
添加一些内容,但是为了测试它是否有效,您正在打印FunctionHookList
中某个对象的ClassName
值。有什么理由相信它们是同一个物体?检查如何构造该对象,然后检查为aCreatedObject
变量赋值的赋值语句。查找有问题的内存操作,例如在调用Move
或TStream.Read
时指定了错误的目标指针或错误的字节计数,从而覆盖了对象的一部分。为了帮助了解发生了什么,请调用
ClassType
< /a> 作用于列表中的对象。 (这通常是安全的调用,因为只要存储在对象引用中的指针指向某个地方,您就会得到一个值。也许不是有效值,但在至少它不会崩溃。)将结果与您期望在列表中的类进行比较。例如,如果您在列表中存储了TFont
,则测试以下内容:It looks like your program is reading from a negative offset of a null pointer. The offset is off by one from the offset where the class name stored in the VMT, suggesting that the field where the object stores its VMT pointer holds the address 1 instead of the actual address of its class's VMT.
That calls into question whether you really stored a valid object reference in that list. You're adding something to
List
, but then, to test that it worked, you're printing theClassName
value of some object inFunctionHookList
. What reason is there to believe those are the same object? Check how you constructed the object, and then check the assignment statement that gives a value to theaCreatedObject
variable. Look for questionable memory operations, like callingMove
orTStream.Read
where you specified the wrong destination pointer or a wrong byte count, thus overwriting a portion of the object.To help find out what's going on, call the
ClassType
function on the object in the list. (That's generally safe to call, because as long as the pointer stored in the object reference points somewhere, you'll get a value. Maybe not a valid value, but at least it won't crash.) Compare the result to the class you expect to be in the list. For example, if you stored aTFont
in the list, then test this:请注意,Assigned 不会检查除 nil 之外的任何内容。如果您将一个对象放入字符串列表中,释放它,然后检查字符串列表,它会告诉您仍然有一个对象。检查这个例子:
所以除了分配的支票之外,几乎所有的支票都是有效的。它只检查对象是否包含除 nil 之外的任何其他值,这基本上与您在上面的行中执行的检查相同。
Please note that Assigned doesn't check anything, except for nil. If you put an object in the stringlist, free it, and then check the stringlist, it will tell you that there's still an object. Check this example:
So almost all your checks are valid, except the assigned. It only checks if the object contains any other value than nil, which it basically the same check you perform on the line above.