CompareMem适合比较两个数组是否相等?

时间:2013-06-18 17:22:27

标签: arrays delphi compare

我需要比较给定数组的所有项是否相同。

目前,我有以下代码:

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');

这个工作正常但是因为CompareMem是用汇编编写的,我还不能(还)理解它的作用。

CompareMem是一种有效的方式来做我想要的吗?此外,我想知道是否适用于每种数据类型,如字符串,整数等。

2 个答案:

答案 0 :(得分:4)

这不是用汇编编写的......如果所有内存都填充了没有间隙的数组项,则比较内存是有效的。通常它会起作用

1)所有数组内存都填充了没有间隙的数据(间隙可能包含垃圾并导致漏报)。

1.1。这应该由packed array关键字强制执行,如果编译器不会忽略它

1.2如果SizeOf(A [1])为2,4,8,16等,则会发生这种情况

但是你最好通过使用不同模式的FillChar进行单元测试来覆盖它 - 它们会模仿垃圾,然后手动填充具有匹配值的数组元素,然后使用CompareMem检查元素是否擦除了所有预先填充的垃圾。

2)数组元素只包含简单的值类型,而不是引用类型。

Char,integer,double,short string,固定大小的数组或由它们组成的记录 - 都是简单类型。

所有其他字符串,指针,对象,接口,动态和开放数组 - 仅仅是指向外部数据的指针,无法通过“内存”进行比较

您可以阅读http://docwiki.embarcadero.com/Libraries/XE2/en/System.Finalize了解更多提示。程序/函数的汇编程序实现也是一个很好的主题,因为它将涵盖不同Delphi数据类型的二进制表示

答案 1 :(得分:4)

CompareMem只是逐字节比较。 CompareMem有两种主要方式无法通过值进行相等性测试:

  1. 正在测试的类型包含填充。
  2. 正在测试的类型是或包含引用类型。
  3. 你问的是数组。由于数组是always packed,因此它们不包含填充。由于您要比较数组值,因此问题可以集中在数组的元素上。

    当且仅当数组元素是不包含填充字节且不包含引用类型的值类型时,才能进行数组的值比较。

    所有简单值类型都是这种情况。

    对于记录,您需要检查记录是否包含引用类型。这必须是递归检查。记录是否包含包含引用类型的记录,依此类推。然后你必须寻找填充。一旦找到填充,使用CompareMem就不合适了。