江湖救急(动态创建数组) ( 积分: 50 )

  • 主题发起人 主题发起人 gggoobm
  • 开始时间 开始时间
G

gggoobm

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个TList里面的Items指向数组,那么,我如何创建这些数组?
不用指针。
 
我试着用函数来返回数组。结果每次返回的地址都是一样的。
我用一个数组变量设定长度为0再重设长度,地址还是一样。。。
只能用指针解决但,指针不好释放。。。请问各位富翁有没什么好法子。。。
不知我描述够不够清楚。
 
刚试了一下List.Add(Copy(array));
结果好像还是不行。。。显示出来的数组都是乱数。
。。。。怎么没人指点一下啊。。。
没人用过TList+数组吗?。。。
 
貌似strings 和 string[] 的关系。

直接写不行吗?
for i:=0 to list.items.count-1 do
list.item.add(string);

你说的数组 是integer,还是string啊?
 
哦整型数组。
其实就是想做一个二维数组。只是用TList比较好删除。。。
就是用TList + array of integer 做个二维整型数组。
List.Add(Copy(array));系统没用维护数组所在的内存空间,那些空间会被使用,导致出现乱数。。。
有没人有什么解决方法。。帮帮忙吧。。。
 
TList 本来是链表,不明白你为什么要用来做什么2维数组.
 
觉得用数组,效率好像比较高。。。那么。。我是不是应该用TList + TList。。。
我在做寻路算法。
每条路径都是一个整型数组。存储相关道路在所在数组的下标值。
路径列表我用TList方便删除
TLine = array of integer;
TLineList = TList; //指向TLine
白前辈。。。有没什么好的建议。
 
直接getmem申请一块内存来保存你的integer列表
然后把内存首地址保存到tlist。

不用时,先释放申请的内存,然后tlist.delete
 
将数组是变量,与所有变量一样,由delphi自动分配空间,然后自动释放,所以不能直接作
链表的item,但可以包装到record里面,win32的写法:

type

Tmyrecord = record
sss: array[2] of integer;
...
end;
pmyrecord = ^Tmyrecord ;

......



var
myitem: pmyrecord;
...

New(myitem);
myitem^.sss[0]:=
 
给个代码,随手写的,未经测试:
var
p,p2: pinteger;
begin
getmem(p,sizeof(Pinteger)* 数组大小);
tlist1.add(p); //保存内容
//修改和访问数据
p2:= p;
inc(p2,4); //移动指针
p2^:= 1234; //修改当前指针指向的值
//如果你已经申请了动态数组,并且对数组的操作代码都已经写好。
那么也可以用move操作把数据复制到新申请的内存上来保存,保存后释放掉数组
end;

释放内存
freemem(tList1.Items) ;
tlist1.delete(i);
 
“另外,还有几个问题需要注意
使用申请的内存前最好调用 fillchar 初始化填充一下
还有
访问内存的地址还可以用这个方法更简便一点,和使用数组感觉是一样的:
p^[X]:= 1234;
这样就可以把p2省略了。”

后来发现上述方法有误,修改了一下:
var p:pinteger;
begin
getmem(p,10);
pinteger(integer(p)+3)^:= 2;
showmessage(inttostr(pinteger(integer(p)+3)^));
freemem(p);
如果p是pchar类型,则可以直接p[X]来访问元素。
 
请教楼上,链表? 前后指针的初始化呢?


LZ干嘛不做一个循环一个一个全读进来,想直接用一个语句把一个数组 按顺序 读到一个链表里面去?

还有,是1维数组还是 2维?2维的话,白河问得好啊,怎么做啊?

个人比较赞同 kinneng 的理解。
 
我的理解是,楼主想搞这么一个东西
1.有很多类似这样的长度不定的数组 1,2,21,34,123,234,456,235,125,……
2.需要把这些数组保存到一个链表内,然后可以遍历这些数组
因此,每个数组getmem一块内存,然后把内存首地址放到tlist内。结束时一个一个释放内存,然后clean tlist,这样不很简单吗?
 
TLine = array of integer;
TLineList = list; //point to TLine
算是二维的。。。
我现在把TLine封装成类,不知会不会有什么负作用。。。
TLine = class //数组受生存期管理的限制,改成类。
private
FValue: TArray;
public
property Value: TArray read FValue write FValue;
procedure SetLen(a_Length: integer);
end;
TLineList = TList; //Point to TLine;
 
个人觉得不对,虽然都是指针,但是TList的Item的指针指向的结构已经被限制了吧?应该跟你的TLine不同,所以强制指向过去的话,会产生错误吧?

不过我还是菜,到现在还是不明白LIST的ITEM的指针指向的地址,存放的数据,自动读取的话,数据类型是String还是Integer啊?我一直认为是String,比如ListBox,ComboBox...都包含了List啊。 现在我有点糊涂了....
 
以我个人而言,是追求访问速度快的,会直接 VirtualAlloc 分配一段平坦内存来操作,1维2维就自己处理好了。
 
jenhon
你说的是TStrings或者说是TStringList;
TList的Item是指针。
白前辈指针的释放对我来说已经是个难题了。。
我还不清楚直接操作内存。。。功夫不够。。呵呵。。。
 
用我给的例子应该能解决楼主的问题了。
操作内存和操作数组没什么区别,数组也是一块内存啊。
就是多一步申请和释放操作罢了。
用我ID:3719595 的修正后的回答,可以直接读写申请到的内存,使用还是很方便的。
pinteger(integer(p)+ X )^:= 2;
X表示指向的第几个元素,为零时指向第一个元素,为1时指向第二个……

至于白河愁说的分配平坦内存的问题,只要数组不是很大,一般在物理内存中也会平坦分布的。
 
List的Item指针的对象,应该有一个明确的类型吧?
就是说,LIST管理了一张链表,链表的内容ITEM是一个个指针,指针指向的内存空间应该有足够的定义信息,LIST才能做管理吧?要不LIST.ITEM.DELETE这个动作,如果LIST简单地把链表截断 重接,那么 被删除的ITEM指向的地址的内容谁来释放?所以我才认为LIST->ITEM地址指向的地方应该已经被DELPHI明确定义了啊,才讨论ITEM的指针类型。

请多多指教。

另:UFO,LZ的意思是要管理一个2维数组,我觉得用LIST的最大好处:可以整行删除,而不用重新排,你看他后面的回答,用的水平还可以哦。

我觉得现在问题就是ITEM的指针是否可以被任意定义类型,LZ自定义了一个类,由这个类的指针来引入到ITEM的指针中。这个应该是讨论的重点啊,可行吗?
 
VAR
AA:ARRAY OF 数据类型
begin
setlength(aa,大小)
aa[0]....这样就行了
end;
 
后退
顶部