相关疑难解决方法(0)

为什么大多数Delphi示例使用FillChar()来初始化记录?

我只是想知道为什么大多数Delphi示例使用FillChar()来初始化记录.

type
  TFoo = record
    i: Integer;
    s: string; // not safe in record, better use PChar instead
  end;

const
  EmptyFoo: TFoo = (i: 0; s: '');

procedure Test;
var
  Foo: TFoo;
  s2: string;
begin
  Foo := EmptyFoo; // initialize a record

  // Danger code starts
  FillChar(Foo, SizeOf(Foo), #0);
  s2 := Copy("Leak Test", 1, MaxInt); // The refcount of the string buffer = 1
  Foo.s = s2; // The refcount of s2 = 2
  FillChar(Foo, SizeOf(Foo), #0); // The refcount …
Run Code Online (Sandbox Code Playgroud)

delphi initialization record

28
推荐指数
3
解决办法
2万
查看次数

如何快速清除简单类型的记录?

我有一个像这样定义的结构:

const
  MaxSignalRecords=255;
type
  TSignalRecord=record
   signal1  : integer;
   signal2  : integer;
   signal3  : integer;
   signal4  : integer;
   signal5  : integer;
   signal6  : integer;
   bsignal1 : Boolean;
   bsignal2 : Boolean;
   bsignal3 : Boolean;
   bsignal4 : Boolean;
   bsignal5 : Boolean;
   bsignal6 : Boolean;
  end;

TListSignals = Array[0..MaxSignalRecords-1] of TSignalRecord;
Run Code Online (Sandbox Code Playgroud)

此结构用于在如下算法中进行数千次计算:

for i:=1 to 900000 do
begin
  CleartheList(MyList);
  DotheMath(MyList);
  DotheChart(MyList);
end;
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种快速的方法来将我的值初始化TListSignals为0和false.

现在我用这个:

procedure ClearListSignals(var ListSignals:TListSignals);
var
  i :Integer;
begin
  for i := 0 to MaxSignalRecords - 1 do …
Run Code Online (Sandbox Code Playgroud)

delphi

28
推荐指数
4
解决办法
2万
查看次数

我需要在Delphi中完成记录数组吗?

在我的申请中,我有以下记录:

TTransaction = record
  Alias: string
  Description: string
  Creation: TDateTime
  Count: Integer
end;
Run Code Online (Sandbox Code Playgroud)

我在这个数组中使用此记录:

Transactions = array of TTransaction;
Run Code Online (Sandbox Code Playgroud)

我在运行时保持数组加载,但在给定时间我需要清除所有数据并添加一些新数据.

仅仅使用它就足够了:

SetLength(Transactions, 0); ?
Run Code Online (Sandbox Code Playgroud)

或者我需要完成一些事情吗?

delphi record finalization dynamic-arrays delphi-6

14
推荐指数
2
解决办法
1万
查看次数

如何初始化声明为局部变量的记录?

我在类的方法中使用由字符串,布尔值,整数,货币和其他记录数组组成的记录.我想以递归方式初始化基本类型的所有字段为空/假/零.默认情况下,Delphi似乎不这样做.是否有一种直接的方法来实现这一点,不涉及通过名称访问每个字段并手动设置它?

delphi

9
推荐指数
1
解决办法
6058
查看次数

Initialize(),Default()和FillChar()之间的区别

假设您有一个您想要初始化的本地记录:

type 
  TMyRec=record
    Val1, Val2:Integer;
  end;

procedure MyProc;
var
  MyVar:TMyRec;
begin
  // ... ?

  WriteLn(Val1,Val2);
end;
Run Code Online (Sandbox Code Playgroud)

除了"手动"设置每个字段外,还有几种方法可以实现.

  1. 使用Initialize():

    Initialize(MyVar);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用默认值():

    MyVar := Default(TMyVar);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用FillChar:

    FillChar(MyVar,SizeOf(MyVar),0);
    
    Run Code Online (Sandbox Code Playgroud)
  4. 定义一个空常量,并将其赋值给var

    const cMyVar:TMyVar=();  
    ...    
    MyVar := cMyVar;    
    
    Run Code Online (Sandbox Code Playgroud)

以上所有似乎都适用于这个例子.我想你甚至可以定义一个全局变量来初始化它.

但是有一种首选方法吗?或者在某些情况下,不建议使用上述任何一种情况,或者它根本不起作用?

把它短,有什么明确的正确方法TM初始化一个局部堆栈变量?:-)

delphi initialization

8
推荐指数
1
解决办法
1570
查看次数

记录在案(无法初始化)

我有2条记录,如下所示:

TYPE
 TRecord2= packed record
  i2: Integer;
 end;

 TRecord1= packed record
  i1: Integer;
  R2: TRecord2;
 end;
Run Code Online (Sandbox Code Playgroud)

.

我想将记录字段初始化为零,但我不想使用FillMemory,因此我声明了2个常量记录,我在其中初始化字段.

CONST
  Record2c: TRecord2=
  (
   i2: 0;
  );

  Record1c: TRecord1=
  (
    i1: 0;
    R2: Record2c;      <------- error line
  );
Run Code Online (Sandbox Code Playgroud)

但是,我无法将Record2c分配给R2字段.编译器说:E2029'('期望但标识符'Record2c'找到.

但这有效(如果我评论我有错误的行):

procedure test;
var Record1: TRecord1;
begin
 Record1:= Record1c;      // initialize variable by associating the constant to it
end
Run Code Online (Sandbox Code Playgroud)

那么,我如何初始化R2字段?

delphi

4
推荐指数
2
解决办法
2257
查看次数

如何完成通过函数的无类型参数传递的记录?

我可以将"任何"记录类型传递给我的程序吗?

我多次使用带有字符串的"记录".

type 
  TR = record
    a: string;
    b: string;
  end;
Run Code Online (Sandbox Code Playgroud)

要清除它们,我需要写:

Finalize(R);
FillChar(R, SizeOf(R), #0);
Run Code Online (Sandbox Code Playgroud)

问题是如何通过任何类型的记录来清除它?

为此我得到了这个提示:"表达式不需要初始化/完成".

procedure ClearRecord(var R);
begin
  Finalize(R);
  FillChar(R, SizeOf(R), #0);
end;
Run Code Online (Sandbox Code Playgroud)

感谢您的每一个信息!

delphi record finalize clear delphi-6

4
推荐指数
1
解决办法
981
查看次数

如何初始化var Record参数

我有记录类型:

type
  TIPInfo = record
    IP,
    HostName,
    City,
    Region,
    Country,
    Loc,
    Org: WideString
  end;
Run Code Online (Sandbox Code Playgroud)

函数返回记录数据:

function GetPublicIPInfo(var IPInfo: TIPInfo): Boolean;
begin
  // initialize
  FillChar(IPInfo, SizeOf(TIPInfo), 0);

  // populate data
  IPInfo.IP := GetVallue('ip');
  IPInfo.HostName := GetVallue('hostname');
  IPInfo.City := GetVallue('city');
  // etc...

  Result := IsOk;   
end;
Run Code Online (Sandbox Code Playgroud)

呼叫者,召集者:

var
  IPInfo: TIPInfo;

if GetPublicIPInfo(IPInfo) then... // use data
Run Code Online (Sandbox Code Playgroud)

它是var TIPInfo通过调用初始化的正确方法FillChar还是应该将每个字段设置为空字符串?来电者应该这样做吗?

此外,out在案例中使用参数会更好吗(因为函数不读取数据)?

delphi delphi-7

3
推荐指数
1
解决办法
740
查看次数

如何设置默认值以在delphi中记录

我正在使用RAD XE7.在我的Delphi应用程序中,我想为Records字段设置默认值.

我尝试了下面的代码,但它没有编译,我知道这是错误的.我还有别的办法吗?

 TDtcData = record
    TableFormat     : TExtTableFormat = fmNoExtendedData;
    DTC             : integer = 0;
    Description     : string = 'Dummy';
    Status          : TDtcStatus;    
    OccurenceCnt    : integer =20;
    FirstDTCSnapShot: integer;
    LastDTCSnapShot: integer;
  end; 
Run Code Online (Sandbox Code Playgroud)

delphi default record delphi-xe7

2
推荐指数
2
解决办法
3740
查看次数

使用Default()赋值在Delphi中初始化记录变量是否安全?

将默认值(TMyRecord)分配给TMyRecord的变量称为内部调用Finalize,然后将内存清零,就像FillChar那样.例如,在以下问题的答案中已经说过,我确实测试过分配Default()确实会导致调用例如System._FinalizeRecord

如何在Delphi中正确释放包含各种类型的记录?

Initialize(),Default()和FillChar()之间的区别

我的问题是,即使在Delphi没有自动调用Initialize的情况下,初始化这样的记录是否总是安全的?对我来说,在未初始化的记录变量上调用Finalize似乎没有意义.在初始化之前,必须假定内存包含随机垃圾.在这种情况下,我对托管类型特别感兴趣,这些托管类型是动态分配内存的指针,Finalize例程应该通过减少它们的引用计数来完成,等等.在许多情况下,Delphi会自动生成对Initialize的调用,以确保其托管类型保持可管理状态.但不总是.

这是一个示例,说明了一个有问题的案例.正如下面的答案所述,你不应该使用GetMem来分配包含这样的托管类型的记录,但是让我们假设某人做了,然后尝试使用Default()赋值作为初始化

type
  TMyRecord = record
    s1, s2, s3 : String;
  end;
  PMyRecord = ^TMyRecord;

var
  pr : PMyRecord;

begin
  GetMem(pr, SizeOf(TMyRecord)); 
  pr^ := Default(TMyRecord);
...
Run Code Online (Sandbox Code Playgroud)

我故意使用GetMem()而不是New(),因为据我所知,GetMem()返回的内存不应该自动归零,并且编译器不应该自动调用Initialize.那么在这种情况下,使用默认分配初始化记录不是不安全吗?

在大卫接受的答案中,他正在使用一种漂亮的Clear方法记录类型 如何在Delphi中正确释放包含各种类型的记录? 让我们添加一个

  TMyRecord = record
    s1, s2, s3 : String;
    procedure Clear;
  end;
...
procedure TMyRecord.Clear;
begin
  Self := Default(TMyRecord);
end;
Run Code Online (Sandbox Code Playgroud)

现在,Clear例程应该完全无法知道记录是否位于堆栈或堆上,并且是否已在其上调用Initialize.

delphi

1
推荐指数
1
解决办法
492
查看次数