事情很简单:做个程序,原先是链表,后来觉得麻烦想用动态数组替代。
找到个相关的资料,不过内存方面不太懂,不太明白意思。
请大家帮我做一段删除动态数组项目的代码,
这里有清空数组和删除数组某项的例子。其中的核心代码:
procedure ClearArr(var A);
var
  P: PLongint; //占用4个字节,正好符合 32 位内存排列
begin
  P := PLongint(A); // 指向 A 的地址
  Dec(P); //P 地址偏移量是 sizeof(A),指向了数组长度
  P^ := 0; // 长度清空
  Dec(P); // 指向引用计数
  P^ := 0; //计数清空。
end;procedure ArrDel(var A;index,Count: Integer);
var
  len, MaxDelete: Integer;
  elSize: Longint;
  P : PLongint; //4 个字节的长整形指针
begin
  P := PLongint(A);// 取的 A 的地址
  elSize := SizeOf(A); // 获取A的长度
  if P = nil then Exit;  // 为空直接退出
  {下面这句完全等同于 Dec(P) ; len := P^  因为 Dec(P) = Pchar(P) – 4
    同样是移动4 字节的偏移量,只不过后者按字节来移动    }
  len := PLongint(PChar(P) - 4)^; // 变量的长度 ,偏移量 -4
  if index >= len then Exit;//要删除的位置超出范围,退出
  MaxDelete := len - index; // 最多删除的数量
  if Count>MaxDelete then Count:=MaxDelete; // 在Count与MaxDelete中取得一个较小值
  if Count = 0 then Exit;// 不要求删除
  Dec(len, Count);// 移动到要删除的位置
  MoveMemory(PChar(P)+index*elSize , PChar(P)+(index + Count)*elSize , (len-index)*elSize); //移动内存
  Dec(P);  //移出 “数组长度”位置
  Dec(P);  //移出“引用计数” 位置
  //重新再分配调整内存,len 新的长度. Sizeof(Longint) * 2 = 2*Dec(P)
  ReallocMem(P, len * elSize + Sizeof(Longint) * 2);
  Inc(P); // 指向数组长度
  P^ := len; // new length
  Inc(P); // 指向数组元素,开始的位置
  PLongint(A) := P;
end;
PS:关于清空数组这一段,似乎并未释放内存?不会引起泄露吗?附上资料地址:http://www.chinaitpower.com/A/2001-10-23/2618.html

解决方案 »

  1.   

    你东西没贴全怎么看
    连分配内存在哪都没看到,看来楼主没打算用面向对象吧
    不过你可以参考TList的源代码,看它的动态列表是怎么做的
    一般是用数组+链表来做
      

  2.   

    发现自己贴出来的这段东西,似乎并不起作用(IDE为D2009)。
    拿出个研究用的模型供大家参考:
    var a:array of string;
        i:integer;
    begin
      SetLength(a,3);
      a[0]:='aaa';a[1]:='bbb';a[2]:='ccc';a[3]:='ddd';
      for I := 0 to 3 do
        ShowMessage(a[i]);目前需要的,就是在这个array of string里面,
    可以在某处插入或删除项目的函数。自己构思过一种方法,就拿插入来说,可以这么做:
    procedure insert(var a:array of string;Index:Integer;Data:string);
    var i:Integer;
    begin
      i:=Length(a);
      SetLength(a,I+1);
      For i:=0 to Length(a)-1 do
        a[Index+i+1]:=a[Index+i];
      a[Index]:=Data;
    end;
    虽然这是个笨办法,但毕竟说得通。
    只可惜想法是好的,只不过编译器不允许:
    [DCC Error] E2008 Incompatible types
    这句话对应的位置,是SetLength(a,I+1);
    如果再深入一点,就会发现,
    编译器在这句中认为dynamic array和array类型不符。其实我也很奇怪,动态数组看不到分配内存。
    链表当然也是方法之一,只不过代码量要比数组大得多。
    至于封装成类,只要有了合适的方法,只是时间问题。在研究的过程中,不幸又产生了新的疑问:可否批量覆盖数组中的内容?
    比如说将数组a的第3项到第5项覆盖为数组b的第4项至第6项的数据?