Jump to content
Ugochukwu Mmaduekwe

Strange Behaviour of FillChar for Non Byte Array Arrays.

Recommended Posts

Hello all, I encountered a weird behaviour of FillChar today.

The Demo below illustrates the bug.

 

program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  SysUtils;

procedure PrintArray(const ar: array of UInt32);
var
  i: Int32;
begin
  for i := Low(ar) to High(ar) do
  begin
    WriteLn(ar[i]);
  end;

end;

var
  a: array [0 .. 5] of UInt32;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    FillChar(a, SizeOf(a), UInt32(4));
    PrintArray(a);
    ReadLn;
  except
    on E: Exception do
      WriteLn(E.ClassName, ': ', E.Message);
  end;

end.

I expected

Quote

4

4

4

4

4

4

 but got the strange values in the image below.

 

strange.jpg.0a5dd5558464b1191bdfad1bac5ced60.jpg

 

 

Any idea what's wrong?

Share this post


Link to post

FillChar is a byte oriented method it will fill the underlying memory with the given number of bytes of the given value. Check Sizeof(a) and you will see that it is 24 and not 6. The UINT32 cast has no effect as FillChar will only use the lowest byte of that parameter.

  • Like 2

Share this post


Link to post

FillChar expects a byte value as the last paramater. You're filling a memory block with byte value 4 and your results show it (67372036 decimal is $04040404).

  • Like 1

Share this post


Link to post
24 minutes ago, Uwe Raabe said:

FillChar is a byte oriented method it will fill the underlying memory with the given number of bytes of the given value. Check Sizeof(a) and you will see that it is 24 and not 6. The UINT32 cast has no effect as FillChar will only use the lowest byte of that parameter.

Oh I see, Thanks for replying.

Is it possible for me to use FillChar on arrays of UInt32 properly?

Let's say an equivalent of FillChar that works with array of UInt32 other than using a loop.

Edited by Ugochukwu Mmaduekwe

Share this post


Link to post
11 minutes ago, Ondrej Kelle said:

FillChar expects a byte value as the last paramater. You're filling a memory block with byte value 4 and your results show it (67372036 decimal is $04040404).

Thanks for the explanation.

Share this post


Link to post
12 minutes ago, Ugochukwu Mmaduekwe said:

Is it possible for me to use FillChar on arrays of UInt32 properly?

In general, no! Unless, in very specific scenarios, when the number you want to fill the array with consists of four similar bytes (like $04040404).

  • Thanks 1

Share this post


Link to post
4 minutes ago, Uwe Raabe said:

In general, no! Unless, in very specific scenarios, when the number you want to fill the array with consists of four similar bytes (like $04040404).

Well thanks for the answer, I guess I will resort to using a for loop for what I want to achieve.

Edited by Ugochukwu Mmaduekwe

Share this post


Link to post
On 12/22/2018 at 2:03 PM, Ugochukwu Mmaduekwe said:

 but got the strange values in the image below.

 

strange.jpg.0a5dd5558464b1191bdfad1bac5ced60.jpg

 

 

Any idea what's wrong?

Yes. Check that 67372036 is the same as hex $04040404, in other words, 4 bytes, each with value 4. FillChar fills bytes, even if you pass a UInt32 or even a UInt64. It will only take the low byte and multiplicate that.

  • Like 1
  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×