【发布时间】:2012-12-20 23:22:58
【问题描述】:
今天我偶然发现了一个导致我的阵列损坏的问题。这是一个可重现的测试用例:
unit Unit40;
interface
type
TVertex = record
X, Y: Double;
end;
TEdge = record
V1, V2: TVertex;
end;
TEdges = array of TEdge;
type
TBoundryInfo = array of TEdges;
procedure MemoryCorrupt;
implementation
procedure MemoryCorrupt;
var
BoundryInfo: TBoundryInfo;
i, PointIndex, BoundryLength: Integer;
begin
BoundryLength := 57;
PointIndex := 0;
SetLength(BoundryInfo, BoundryLength);
for i := 0 to BoundryLength - 1 do
begin
if i <> 17 then
begin
SetLength(BoundryInfo[i], 1);
BoundryInfo[i][0].V1.X := 1;
BoundryInfo[i][0].V2.X := 1;
BoundryInfo[i][0].V1.Y := 1;
BoundryInfo[i][0].V2.Y := 1;
end else
begin
SetLength(BoundryInfo[i], 2);
BoundryInfo[i][0].V1.X := 1;
BoundryInfo[i][0].V2.X := 1;
BoundryInfo[i][0].V1.Y := 1;
BoundryInfo[i][0].V2.Y := 1;
BoundryInfo[i][1].V1.X := 1;
BoundryInfo[i][1].V2.X := 1;
BoundryInfo[i][1].V1.Y := 1;
BoundryInfo[i][1].V2.Y := 1;
end;
end;
BoundryLength := 9;
SetLength(BoundryInfo, BoundryLength);
Move(BoundryInfo[PointIndex+1], BoundryInfo[PointIndex],
((BoundryLength - 1) - PointIndex) * SizeOf(BoundryInfo[PointIndex]));
Dec(BoundryLength);
Finalize(BoundryInfo[BoundryLength]);
SetLength(BoundryInfo, BoundryLength); //After this, arrays contains garbage
BoundryInfo[0][0].V1.X := 3;
end;
end.
我猜最后一个SetLength 之后的内存损坏只是Move 使用不当的症状。
有人可以向我解释我做错了什么以及在这种情况下如何正确使用Move?
在原始问题中,我在循环中从 BoundryInfo 中删除元素,这就是为什么我调用 Finalize(BoundryInfo[BoundryLength])
【问题讨论】:
-
天啊!我成为水平滚动的受害者。如果看不到整个代码,则无法诊断代码问题。
-
简单的解决方案是停止使用 Move。
-
@DavidHeffernan 我害怕这样的答案,这就是为什么我写了“......在这种情况下如何正确使用 Move?”
-
嗯,根据我的经验,在这里移动通常是错误的方法。
标签: delphi memory-management multidimensional-array delphi-2009