【发布时间】:2015-11-10 22:50:31
【问题描述】:
我在使用 Delphi 的 TMemoryStream(或 TFileStream)时遇到了一个奇怪的问题。在将流的一部分读入字节数组时。下面是一些代码作为示例。
procedure readfromstream();
var
ms : TMemoryStream;
buffer : array of byte;
recordSize : Integer;
begin
try
begin
ms := TMemeoryStream.Create();
ms.LoadFromFile(<some_path_to_a_binary_file>);
while ms.Position < ms.Size do
begin
buffer := nil;
SetLength(buffer, 4);
ms.ReadBuffer(buffer, 4);
move(buffer[0], recordSize, 4);
SetLength(buffer, recordSize);
ms.Position := ms.Position - 4; // Because I was having issues trying to read the rest of the record into a specific point in the buffer
FillChar(buffer, recordSize, ' ');
ms.ReadBuffer(buffer, recordSize); // Issue line ???
// Create the record from the buffer
end;
finally
begin
ms.Free();
end;
end;
过程被称为,
// Some stuff happens before it
readfromstream();
// Some stuff happens after it
在调试时,我可以看到它将流读入缓冲区,并且记录适当地存储在内存中。然后程序正常退出,调试器退出程序,但我最终直接回到程序并重复。
通过强制程序过早退出,我认为问题涉及ms.ReadBuffer(buffer, recordSize);,但我不明白为什么会导致问题。
这个过程只被调用一次。我的测试数据只有一个条目/数据。 任何帮助将不胜感激。
【问题讨论】:
-
欢迎来到 SO。你分析调用堆栈了吗?该程序必须由某人或某事调用。你的程序对事件有反应吗?
-
谢谢。我忘了提到,是的,我做到了,它只在调用堆栈中出现一次,并且来自它上面的函数。我可能错过了一些东西,关于如何仔细检查的任何提示。
-
FWIW,这不是您的真实代码(没有
TMemeoryStream类型,AFAICT)。所以可能有我们看不到的问题,因为它们可能在手动复制过程中丢失了,或者我们在这里看到了原始代码中没有的问题,出于同样的原因。请使用复制和粘贴在此处复制您的代码。不要重新输入。 -
正如@David 所说,您正在复制指针和后续字节。由于这是在堆栈上,并且堆栈向下增长,这意味着您正在覆盖堆栈的相当一部分(413 字节?)。反过来,这意味着几个局部变量、堆栈上的返回地址以及任何任何参数以及可能大量的调用堆栈帧、返回地址和参数都被覆盖。那种严重的堆栈损坏会导致各种可怕的问题,而无限循环只是其中之一。
-
@RudyVelthuis 感谢您的解释,这正是在大卫说我导致内存损坏后我所想的。不幸的是,我仍然无法按照 David 解释的方式在 recordSize 中读取它,所以稍后我将不得不再看一遍
标签: delphi delphi-xe8