CompareMem suitable for comparing two arrays for equality?

I need to compare if all elements of a given array are the same.

I currently have the following code:

Type TD = array [0..1] of TDateTime; var A: TD; B: TD; begin A[0] := Date-1; A[1] := Date+1; B[0] := Date-1; B[1] := Date+1; if CompareMem(@A, @B, SizeOf(TD)) then Showmessage('Equals') else Showmessage('Differ'); 

This works fine, but since CompareMem is written in assembly, I still cannot figure out what it does.

Is CompareMem the right way to do what I want? In addition, I would like to know if each data type such as string, integer, etc. will work.

+4
source share
2 answers

This is not written in the assembly ... A memory comparison is valid if all memory is filled with array elements without spaces. This usually works if

1) All array memory is filled with data without spaces (a gap may contain garbage and cause a false negative result).

1.1. this should be done using the packed array keyword if the compiler doesn't ignore it

1.2 this should happen if SizeOf (A [1]) is 2,4,8,16, etc.

But it’s better to clean it with unit tests, using FillChar with different templates - they will simulate garbage, then manually fill the array elements with the appropriate values, and then check with CompareMem that the elements destroyed all the pre-filled garbage.

2) The array elements contain only simple value types, not reference types.

Char, integer, double, short strings, arrays of a fixed size or records from them are simple types.

All other lines, pointers, objects, interfaces, dynamic and open arrays - just point to external data and can not be compared "by memory"

You can read about http://docwiki.embarcadero.com/Libraries/XE2/en/System.Finalize for more tips. An assembly-based implementation of procedures / functions would also be a good topic, since it would cover binary representations of different Delphi data types.

+4
source

CompareMem just does a byte comparison. There are two main ways in which CompareMem cannot be valid for checking equality by value:

  • Checked types contain indents.
  • Those types that are tested contain or contain reference types.

You are asking about arrays. Since arrays are always packed , they are not indented. Since you are comparing array values, the question may focus on array elements.

Comparing array values ​​will be an appropriate task if and only if the elements of the array are value types that do not contain padding bytes and do not contain reference types.

This applies to all simple value types.

For records, you need to check if the record contains reference types. This should be a recursive check. Does the record have records containing reference types, and so on. And then you should look for additions. Once you find the registration, using CompareMem not suitable.

+4
source

Source: https://habr.com/ru/post/1486881/


All Articles