事情很简单:做个程序,原先是链表,后来觉得麻烦想用动态数组替代。
找到个相关的资料,不过内存方面不太懂,不太明白意思。
请大家帮我做一段删除动态数组项目的代码,
这里有清空数组和删除数组某项的例子。其中的核心代码:
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
找到个相关的资料,不过内存方面不太懂,不太明白意思。
请大家帮我做一段删除动态数组项目的代码,
这里有清空数组和删除数组某项的例子。其中的核心代码:
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
连分配内存在哪都没看到,看来楼主没打算用面向对象吧
不过你可以参考TList的源代码,看它的动态列表是怎么做的
一般是用数组+链表来做
拿出个研究用的模型供大家参考:
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项的数据?