【问题标题】:local variable initialized in delphi?在delphi中初始化的局部变量?
【发布时间】:2014-11-28 12:43:23
【问题描述】:

在审查旧程序代码的过程中,出现了以下问题:方法中的所有局部变量都在开始后立即初始化。通常不初始化局部变量。但是我们有一个过程,其中所有变量都初始化为 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;

【问题讨论】:

  • 这真的是那个 Q @TLama 的骗子吗?
  • @David,那里有答案。但是,例如this one 更好。会有更多... [我会重新打开这个]
  • @TLama “这个”问题与方法/过程中的局部变量无关,而是与全局变量有关。我更喜欢用于复制的那个。
  • @Lasse,是的,但如果我们是迂腐的,我们可以按照标题到重复的问题链接说“这个问题已经在这里有答案”。这两个问题都有答案。我会亲自将询问“非托管类型的局部变量如何初始化?”的问题与询问“变量一般如何初始化?”的问题联系起来。 .
  • @DavidHeffernan:虽然我确实同意将所有内容放在一个自上而下的回复中很好——关于简短的回答,也有一些话要说。由于我正在从 D2006 移植一个遗留项目(使用 TMS unicode hell),因此我在谷歌上搜索了所有已发生的字符串更改以仔细检查 10.2 的状态。我必须点击 8 次才能找到答案 861045,然后是这个。我只能想象这是一个完整的新手体验。也许允许一些直接的答案通过,然后在对主要回复的引用中发表评论?

标签: delphi variables initialization


【解决方案1】:

这只是机会。变量未初始化。该变量将驻留在堆栈中,如果碰巧最后写入堆栈的该位置的内容为零,那么那里的值仍然为零。

非托管类型的局部变量未初始化。不要让上述巧合说服你。

考虑这个程序:

{$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

正如您可能想象的那样,许多不同的事情都可能导致堆栈空间的内容发生变化。所以相信你所知道的。非托管类型的局部变量未初始化。

【讨论】:

  • 我也期望得到不同的初始化值,但是当我添加一个非常大的数组(2000x100)时,数组的所有值也被初始化为零。对于未初始化的变量非常不切实际。另外,我在调用上述方法之前直接添加了一个方法,在该方法中我用 $FF 初始化了一个数组(大小为 100x100)。再一次:上述方法中的所有内容都为 0。
  • 我不知道该评论什么。就好像你不相信我一样。
  • @elite 有什么不切实际的?当您的机器关闭时,RAM中没有电流真的不可靠吗?所以当你打开它时,你的大部分 RAM 恰好处于全零的默认状态?在您的程序开始运行之前发生某些事情来清除现在分配调用堆栈的内存块是不现实的吗? (操作系统可能会在启动您的应用程序之前初始化调用堆栈。但这只会发生一次 - 这就是您不能依赖它的原因。如果操作系统确实初始化了调用堆栈 - 这可能会改变.)
  • @elite 如果您想提供一个简单的示例来演示您使用 $FF 初始化数组的测试未按预期工作,我们可以解释您做错了什么。 (我猜你可能使用了动态数组。)
  • 经过更多测试后,我得出的结论是,这里的行为似乎是一连串的可能性,在我的情况下总是导致内存为零。也许它与函数所需的内存量有关,但我并不确切知道。感谢您的耐心等待。
猜你喜欢
  • 2021-03-17
  • 2016-09-07
  • 2012-10-03
  • 2017-05-14
  • 2016-01-14
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多