Reputation: 2014
I believe that local integer variables are not initialized to zero in delphi. The initial value is whatever happens to be at that memory location. So in the code below the first time the button is clicked the first message shows a integer value. How come the second time it's clicked it doesn't show 3 but instead shows the same integer value? It continues to show the same integer value each time I click the button. The value is different only when I stop and restart the program. Where is 3 being stored as it looks like the same memory location is used each time the button is clicked in the same run of the program?
procedure TForm1.Button1Click(Sender: TObject);
var
int1 : integer;
begin
showmessage(inttostr(int1)) ;
int1 := 3;
end;
end.
Upvotes: 6
Views: 6947
Reputation: 7625
Initializng variables may or may not be done by the memory manager.
I would consider it good practice of any memory manager to initialize all variables to zero (0x0000). Thats done in .Net as well.
Upvotes: 0
Reputation: 32334
This will only be true if you execute no other code between two clicks on Button1, most importantly code that uses the same amount of (or more) stack space than the code to arrive at procedure TForm1.Button1Click() uses. Unless you overwrite values on the stack they will still contain the same value.
What you could do to test this is to add another button with an OnClick handler that calls a method with more parameters than ShowMessage() has. If you click that button between two clicks on Button1, the value of int1 should indeed change. That is because the stack location for int1 in Button1Click() will then be used for one of the parameters in your other handler, and get overwritten.
The assignment should be optimized away, you can see this as the line should not have the blue dot in the gutter area. There should be a compiler hint as well.
Edit: As you commented there seems to be no change in behaviour when another button is clicked. From that I can only assume that the VCL code (which is executed before the OnClick handler is called) uses so much stack space that the memory location for int1 is always initialized with some (stable) value. This code does always the same, so if the addresses of the involved objects (Application, parent form and button) do not change the value will also stay the same. OTOH restarting the application will yield a new, equally stable value in the uninitialized local variable.
Note that this is all highly dependent on the VCL code executed before the handler, so changes to the VCL might change it too. It may even be that various Delphi versions already behave differently.
Upvotes: 2
Reputation: 12898
Do you want it to be the same? If so, you could use a local const:
procedure TForm1.Button1Click(Sender: TObject);
const
i: integer = 0;
begin
i := i + 1;
edit1.text := intToStr(i);
end;
You have to assure 'Assignable typed constants' is switched on though.
Upvotes: 1
Reputation: 53366
Local variables are in the stack frame. And they are not initialized.
If you access a method twice, you have a chance the stackpointer is euqal which gives the same values.
Example:
Stack before call:
> More stack (memory location X)
If Button1Click is called, the stack is like:
> Int1
> Return address
> Sender
> Self pointer
> More stack (memory location X)
If the next time, Button1Click is called, the stackpointer is still on location X, and no other function has changed the values, you will find the same value for Int1.
If you have secure information, it is always wise to clear the local variables (but you have a chance that the optimizer removes these states. So you neet to disable optimizing).
Just for fun, add another button:
procedure TForm1.Button2Click(Sender: TObject);
var
int1 : integer;
begin
showmessage(inttostr(int1)) ;
int1 := 777;
end;
And check:
Upvotes: 1
Reputation: 58441
kjack,
It contains whatever value is in the stack frame at that time. In your case, this will be Sender. If you'd take the integer and typecast it to an object you'll notice the "pattern".
procedure TForm1.Button1Click(Sender: TObject);
var
int1 : integer;
begin
ShowMessage(TObject(int1).ClassName);
showmessage(inttostr(int1)) ;
int1 := 3;
end;
end.
Upvotes: 12
Reputation: 10064
Firstly, you're correct that local variables aren't initialised.
Also you can't guarantee that int1
is being stored in the same memory location on each invocation. In this case it could be that the reason you're seeing the same value each time is because it is using the same location (by chance) but the Delphi compiler has optimised away your final
int1 := 3;
statement as it has no effect. (You can add another showmessage(inttostr(int1))
call after that line and see if that makes a difference.) Another possibility is that the memory location used for int1
is reused between calls to your button handler (say in the Windows message loop) and that happens to always reset it to the value you're seeing.
Upvotes: 5