在旧程序代码的审核过程中出现以下问题:方法中的所有局部变量在开始后立即初始化。通常局部变量未初始化。但是我们有一个程序,其中所有变量都被初始化为0.是否有人知道如何发生这种情况?
示例:
type
TPrices = array[0..10, 0..5] of Integer;
procedure DoSomething();
var
mPrices : TPrices;
mValue : Integer;
begin
if (mPrices[0,0] = 0) then
MessageDlg('Zero', mtInformation, [mbOK], 0);
if (mValue = 0) then
MessageDlg('Zero Integer', mtInformation, [mbOK], 0);
end;
答案 0 :(得分:5)
这只是机会。变量未初始化。变量将驻留在堆栈上,如果发生这种情况,那么最后写入堆栈位置的任何内容都为零,那么那里的值仍然为零。
未初始化非托管类型的局部变量。不要让像上面这样的巧合说服你。
考虑这个程序:
{$APPTYPE CONSOLE}
type
TPrices = array[0..10, 0..5] of Integer;
procedure Foo;
var
mPrices: TPrices;
begin
Writeln(mPrices[0,0]);
end;
begin
Foo;
end.
当我在我的机器上运行时,输出为:
1638012
现在考虑一下这个程序:
{$APPTYPE CONSOLE}
type
TPrices = array[0..10, 0..5] of Integer;
procedure Foo;
var
mPrices: TPrices;
begin
Writeln(mPrices[0,0]);
FillChar(mPrices, SizeOf(mPrices), 0);
end;
procedure Bar;
var
mPrices: TPrices;
begin
Writeln(mPrices[0,0]);
end;
begin
Foo;
Bar;
end.
这次输出是:
1638012 0
碰巧两个函数将它们的局部变量放在同一个位置,并且第一个函数调用在返回之前将局部变量归零,这会影响第二个函数中另一个局部变量的未初始化值。
或试试这个程序:
{$APPTYPE CONSOLE}
type
TPrices = array[0..10, 0..5] of Integer;
procedure Foo;
var
mPrices: TPrices;
begin
Writeln(mPrices[0,0]);
FillChar(mPrices, SizeOf(mPrices), 0);
mPrices[0,0] := 666;
end;
procedure Bar;
var
mPrices: TPrices;
begin
Writeln(mPrices[0,0]);
Writeln(mPrices[0,1]);
end;
begin
Foo;
Bar;
end.
现在输出是:
1638012 666 0
正如您可能想象的那样,许多不同的事情可能会导致堆栈空间的内容发生变化。相信你所知道的。非托管类型的局部变量未初始化。