还忘了一点:C++中的字节拷贝memcpy在delphi中相应的是什么?我找到了Fillchar和Move,对不对?

解决方案 »

  1.   

    还是我,我有想到一点,C++中的动态数组直接用指针实现,而对数组的索引是与数组元素的字节长度相关的。比如:int *A;A[1]的地址是:起始地址+
    1*sizeof(int),所以A[1]表示数组中的第二个整型值,而不是A的后一个字节的值。但我上面的程序中几个地方我想不通:
    memcpy(&(DataStream[ItemNum]),Item,ItemSize);
    这里是指针间的拷贝,没什么说的。
    for(int i=Index;i<ItemNum;i++)
      {
        DataStream[i]=DataStream[i+1];
      }
    //这里又是怎么回事?我写的时候,全是感觉,运行也正确,可一想,不对啊,DataStream是unsigned char*而不是Stash*,DataStream[1]应该指向第
    二个字节才对,而程序中指向了第二个int型值,DataStream怎么知道存在他里面的是以32字节为单位的int型呢?
    劳驾帮我分析一下,感激不尽。
      

  2.   

    delphi中的确用move
    如:
    var  A: array[1..4] of Char;
      B: Integer;
    begin
      Move(A, B, SizeOf(B));  { SizeOf = safety! }
    end;其它问题我还在看
      

  3.   

    DataStream不知道,但编译器知道啊:)
    因为你是这样为它分配内存的呀
    DataStream=(unsigned char*)malloc(10*sizeof(ItemSize));
    而ItemSize是int,不是吗?
      

  4.   

    我的代码class 部分unit Stash;interfaceuses
      classes, SysUtils;type
      TStash = class
      private
        FItemSize, FItemNum, FSize: Integer;
        FDataStream: PPointerList; // PPointerList = ^TPointerList;
                                   //TPointerList = array[0..MaxListSize - 1] of Pointer;
      public
        constructor Create(ItemLen: Integer);
        destructor Destroy; override;
        procedure Add(Item: Pointer);
        procedure Del(Index: Integer);
        function Get(Index: Integer): Pointer;    property Count: Integer read FItemNum;
      end;implementationconstructor Tstash.Create(ItemLen: Integer);
    begin
      FItemSize := ItemLen;
      FItemNum := 0;
      FSize := 0;
      GetMem(FDataStream, 10 * FItemSize);
    end;destructor TStash.Destroy;
    begin
      FItemNum := 0;
      FreeMem(FDataStream);
    end;procedure TStash.Add(Item: Pointer);
    begin
      if FItemNum >= FSize then
      begin
        ReallocMem(FDataStream, (FSize + 10) * FItemSize);
        Inc(FSize, 10);
      end;
      system.Move(Item, Fdatastream^[FItemNum], FItemSize);
      Inc(FItemNum);
    end;procedure TStash.Del(Index: Integer);
    begin
      if (Index >= FItemNum) or (Index < 0) then Exit;
      system.Move(FDataStream^[Index + 1], FDataStream^[Index], (FItemNum - Index) * FItemSize);
      Dec(FItemNum);
    end;function TStash.Get(Index: Integer): Pointer;
    begin
      if (Index >= FItemNum) or (Index < 0) then Exit;
      Result := FDataStream^[Index];
    end;end.
      

  5.   

    窗口测试部分unit frmMain;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Stash;type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private    { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      Stash: TStash;
      I: Integer;
      a, b, c: Integer;
    begin
      Stash := TStash.Create(sizeof(Integer));
      //for I := 0 to 5 do  Stash.Add(@I);
      //error! @I都是同一地址!!!调用Del时会出错
      a := 0;
      b := 1;
      c := 2;
      //correct! a,b,c 变量的地址都不同!
      try
        with Stash do
        begin
          Add(@a);
          Add(@b);
          Add(@c);
        end;
        Memo1.Lines.Clear;
        for I := 0 to Stash.Count - 1 do
          Memo1.Lines.Add(IntToStr(integer(Stash.Get(I)^)));    Memo1.Lines.Add('');
        Stash.Del(0);
        for I := 0 to Stash.Count - 1 do
          Memo1.Lines.Add(IntToStr(integer(Stash.Get(I)^)));
      finally
        Stash.Free;
      end;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      close;
    end;end.
      

  6.   

    另:我觉得你的c++代码有问题啊
    比如init中的
    ItemSize=ItemLen
    DataStream=(unsigned char*)malloc(10*sizeof(ItemSize));
    而你调用时是intStash.Init(sizeof(int));
    ItemLen已经是长度了,何必还要sizeof(ItemSize)?还有
    for(i=0;i<=30;i++)
        intStash.Add(&i);
    c++编译器中不会每次为i重新分配地址
    因此,加入的都是同一个地址
    i++后,intStash中的值也会随着便,而且所有的值都会相同!!
    你的运行之所以正确,是因为你仍用了同一个i做for的循环变量!
      

  7.   

    哈哈,解决了:
    unit Unit2;interface
    uses
      classes,sysutils,windows;
    type
      TStash = class
      private
        FItemSize:Integer;
        FItemNum:Integer;
        FSize:Integer;
        FDataStream: Array of Pointer;
      public
        constructor create(ItemLen:Integer);
        destructor destroy;
        procedure Add(Item:Pointer);
        procedure Del(Index:Integer);
        function Get(Index:Integer):Pointer;
        property Count:Integer read FItemnum;
      end;implementation{ TStash }procedure TStash.Add(Item: Pointer);
    begin
      if FItemNum>=FSize then
      begin
        SetLength(FDataStream,FSize+10);
        Inc(FSize,10);
      end;
      GetMem(FDataStream[FItemNum],FItemSize);
      MoveMemory(FDataStream[FItemNum],Item,FItemSize);
      Inc(FItemNum);
    end;constructor TStash.create(ItemLen: Integer);
    begin
      FItemSize:=ItemLen;
      FItemNum:=0;
      FSize:=10;
      SetLength(FDataStream,10);
    end;procedure TStash.Del(Index: Integer);
    begin
      if (Index>=FItemNum) or (Index<0) then
        exit;
      System.Move(FDataStream[Index+1],FDataStream[Index],
       (FItemNum-Index)*FItemSize);
      Dec(FItemNum);
    end;destructor TStash.destroy;
    begin
      FItemNum:=0;
      FreeMem(FDataStream);
      inherited;
    end;function TStash.Get(Index: Integer): Pointer;
    begin
      if (Index>=FItemNum) or (Index<0) then
        exit;
      result:=FDataStream[Index];
    end;end.
    //////////////////////////////
    procedure TForm1.Button1Click(Sender: TObject);
    var
      i,j:integer;
      intStash:TStash;
    begin
      intStash:=TStash.create(sizeof(integer));
      for i:=0 to 10 do
        intStash.Add(@i);
      for j:=0 to intStash.Count-1 do
      begin
        i:=Integer(intStash.Get(j)^);
        ListBox1.AddItem(IntToStr(i),ListBox1);
      end;
      //
      intStash.Del(1);
      for j:=0 to intStash.Count-1 do
      begin
        i:=Integer(intStash.Get(j)^);
        ListBox1.AddItem(IntToStr(i),ListBox1);
      end;
    end;
      

  8.   

    更正:
    procedure TStash.Del(Index: Integer);
    var
      i:integer;
    begin
      if (Index>=FItemNum) or (Index<0) then
        exit;
      Dec(FItemNum);
      for i:=Index to FItemNum-1 do
        CopyMemory(FDataStream[i],FDataStream[i+1],FItemSize);
    end;