全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4886
推到 Plurk!
推到 Facebook!

陣列的宣告與釋放

答題得分者是:dllee
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-10-14 15:05:26 IP:61.222.xxx.xxx 未訂閱
請問各位一個觀念問題 我在 public 建立一個動態陣列 var adata: array of string; 然後在程式中, 因需要會時常做 setlength(adata, length(adata) 1); i:= length(adata); adata[i]:= 'my string'; 也就是不特定時間(當user有執行到某一行為時), 就會重設陣列值, 再把一特定字串給予該adata值, 我的疑問題, 如果程式不斷的做setlength來改變陣列值(一次運作中可能會有數十次的變動), 那對記憶體的配置是否會造成影響, 例如說資源耗竭現象, 但我又不可能先做setlength(adata,0)來釋放, 因為我必須保有先前的值, 但我實測的作業中似乎查覺不出有任何資源的耗損(我曾測試到一次運作1000次的setlength) , 好像是沒有影響, 但不知各位網友對這方面是否有更好的經驗指點! 謝謝! 另外, 如果我設定陣列值為10個, 而我想移除第6個陣列值, 並使其陣列值成為9個, 原來的第7個變為第6個, 有沒有最簡單的方式可以做到, 我現在能想到的是指定一個 b陣列, 將 a陣列一個一個複製到 b, 然後除掉 a[5]的陣列後, 再把 b陣列重新轉入 a陣列 (a:=b) ps:本案一定要使用動態設定陣列, 而且一定要用陣列來做! 發表人 - P.D. 於 2002/10/14 16:52:56
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2002-10-20 13:08:05 IP:203.204.xxx.xxx 未訂閱
引言: 請問各位一個觀念問題 我在 public 建立一個動態陣列 var adata: array of string; 然後在程式中, 因需要會時常做 setlength(adata, length(adata)+1); i:= length(adata); adata[i]:= 'my string'; 也就是不特定時間(當user有執行到某一行為時), 就會重設陣列值, 再把一特定字串給予該adata值, 我的疑問題, 如果程式不斷的做setlength來改變陣列值(一次運作中可能會有數十次的變動), 那對記憶體的配置是否會造成影響, 例如說資源耗竭現象, 但我又不可能先做setlength(adata,0)來釋放, 因為我必須保有先前的值, 但我實測的作業中似乎查覺不出有任何資源的耗損(我曾測試到一次運作1000次的setlength) , 好像是沒有影響, 但不知各位網友對這方面是否有更好的經驗指點! 謝謝!
這個問題與這個 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=21717 有點類似,同樣是不會有資源浪費的問題。
引言: 另外, 如果我設定陣列值為10個, 而我想移除第6個陣列值, 並使其陣列值成為9個, 原來的第7個變為第6個, 有沒有最簡單的方式可以做到, 我現在能想到的是指定一個 b陣列, 將 a陣列一個一個複製到 b, 然後除掉 a[5]的陣列後, 再把 b陣列重新轉入 a陣列 (a:=b) ps:本案一定要使用動態設定陣列, 而且一定要用陣列來做!
如果一定要用陣列來做!那您所說的方法就是唯一的方法。 如果可以不用陣列來作,那方法就很多種,最簡單的是改用 TStringList,用它的 Add/Insert/Delete 就可以動態新增/插入/刪除比陣列要好用得多,而其 Strings[Index] 的屬性用起來也與陣列無異! 沒空更新的網頁...
C及指標教學,計算機概論,資訊管理導論... http://coolsite.to/dllee 介紹Shells,LiteStep,GeoShell.... http://coolsite.to/ushells
------
http://www.ViewMove.com
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2002-10-20 20:38:10 IP:61.66.xxx.xxx 未訂閱
引言: 如果一定要用陣列來做!那您所說的方法就是唯一的方法。 如果可以不用陣列來作,那方法就很多種,最簡單的是改用 TStringList,用它的 Add/Insert/Delete 就可以動態新增/插入/刪除比陣列要好用得多,而其 Strings[Index] 的屬性用起來也與陣列無異!
其實最早我即是以TStringList來做, 但因為我要的型態很多種而很多個欄位要指定, 很麻煩而且記憶體吃得很大, 所以我才會用陣列來做, 該陣列是屬於記錄型態(array of TRecord), 這樣我只要指定一個陣列就包含了我要的所有欄位內容, 在日後的維護及程式的可讀性會具有較可塑性! 謝謝!
Emulator
一般會員


發表:1
回覆:18
積分:8
註冊:2002-10-17

發送簡訊給我
#4 引用回覆 回覆 發表時間:2002-10-21 00:55:43 IP:211.74.xxx.xxx 未訂閱
 
type dataNode = record
    data : char;
    isDeleted : bool;
end;    type TArrSimLL = class
    private
        dataArray : array of dataNode;
        srcPos : integer;    // reserved for FindNext;
        topNode : integer;
        function srcIndex(indexNumber:integer):integer;// find the real index Postion
        procedure reAllocMemory(arrayNumber:integer);
    public
        constructor Create(arrayNumber:integer);
        destructor Destroy;override;
        procedure Add(index:integer; idata:char);
        procedure Append(idata:char);
        procedure delete(index:integer);
        function find(fData:char):integer;
        function Travel:string;
    end;
//---------------TArrSimLL Class Func-----------------------//
//==========private=========//
function TArrSimLL.srcIndex(indexNumber:integer):integer;
var
    loop : integer;
    jmpNumber : integer;
begin
    jmpNumber:=0;
    for loop:=0 to indexNumber-1 do
    begin
        if dataArray[loop].isDeleted then jmpNumber:=jmpNumber 1;
    end;
    Result:=jmpNumber indexNumber-1;
end;
procedure TArrSimLL.reAllocMemory(arrayNumber:integer);
var
    newDataArray : array of dataNode;
    bkpLoop : integer;
    nIndex : integer;
begin
    setLength(newDataArray,arrayNumber);
    nIndex:=0;
    for bkpLoop:=0 to arrayNumber-1 do
    begin
        with newDataArray[bkpLoop] do
        begin
            isDeleted:=False;
            data:=#0;
        end;
    end;
    for bkpLoop:=0 to Length(dataArray)-1 do
    begin
        if not dataArray[bkpLoop].isDeleted then
        begin
            newDataArray[nIndex].data:=dataArray[bkpLoop].data;
            nIndex:=nIndex 1;
        end;
    end;
    srcPos:=-1;
    topNode:=nIndex-1;
    setLength(dataArray,arrayNumber);
    dataArray:=@newDataArray[0];
    newDataArray:=nil;
end;
//==========private end======//
//==========public===========//
constructor TArrSimLL.Create(arrayNumber:integer);
begin
    srcPos:=-1;
    topNode:=-1;
    setLength(dataArray,arrayNumber);
end;
destructor TArrSimLL.Destroy;
begin
    inherited;
//doing nothing
end;
procedure TArrSimLL.Add(index:integer; idata:char);
var
    bkpLoop : integer;
begin
    if topNode=Length(dataArray)-1 then reAllocMemory(Length(dataArray)*2);
    if( (index>-1) and (index<=topNode 1) ) then
    begin
        if not dataArray[index].isDeleted then
        begin
            for bkpLoop:=topNode downto index do
            begin
                with dataArray[bkpLoop] do
                begin
                    dataArray[bkpLoop 1].data:=data;
                    dataArray[bkpLoop 1].isDeleted:=isDeleted;
                end;
            end;
            dataArray[index].data:=idata;
            dataArray[index].isDeleted:=False;
            topNode:=topNode 1;
        end
        else
        begin
            dataArray[index].data:=idata;
            dataArray[index].isDeleted:=False;
        end;
    end
    else ShowMessage('index is out of bound');
end;
procedure TArrSimLL.Append(idata:char);
begin
    if topNode=Length(dataArray)-1 then reAllocMemory(Length(dataArray)*2);
    topNode:=topNode 1;
    dataArray[topNode].data:=idata;
    dataArray[topNode].isDeleted:=False;
end;
procedure TArrSimLL.delete(index : integer);
var
    dLoop : integer;
    jmp : integer;
begin
    jmp:=0;
    for dLoop:=0 to index do
    begin
        if dataArray[dLoop].isDeleted then jmp:=jmp 1;
    end;
    jmp:=jmp index;
    if jmp    最近的作業..順便貼上來..
在The Tomes of Delphi Algorithms and Data Structures有更好的作法..
只是礙於作業題目限制所以就沒用了..
不過這個方法我覺得稍微改一下,應該可以用在你的需求上..:)    = Delphi - Emulator =
        
------
= Delphi - Emulator =
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2002-10-21 18:11:20 IP:61.231.xxx.xxx 未訂閱
引言:
引言: 如果一定要用陣列來做!那您所說的方法就是唯一的方法。 如果可以不用陣列來作,那方法就很多種,最簡單的是改用 TStringList,用它的 Add/Insert/Delete 就可以動態新增/插入/刪除比陣列要好用得多,而其 Strings[Index] 的屬性用起來也與陣列無異!
其實最早我即是以TStringList來做, 但因為我要的型態很多種而很多個欄位要指定, 很麻煩而且記憶體吃得很大, 所以我才會用陣列來做, 該陣列是屬於記錄型態(array of TRecord), 這樣我只要指定一個陣列就包含了我要的所有欄位內容, 在日後的維護及程式的可讀性會具有較可塑性! 謝謝!
不知道您有沒有利用過 TStringList 中的 Objects[Index] ? 我都利用它來存一個 Record ,利用 AddObject(String,Object) 來加入,而 Strings[Index] 就變成它的索引,可以利用 IndexOf(String) 自動去找,不用自己寫程式 很方便說... 發現了 ><>< src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=6939849&CC=155211">
C及指標教學,計算機概論,資訊管理導論... http://coolsite.to/dllee 介紹Shells,LiteStep,GeoShell.... http://coolsite.to/ushells
------
http://www.ViewMove.com
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2002-10-21 21:27:58 IP:61.66.xxx.xxx 未訂閱
引言: 不知道您有沒有利用過 TStringList 中的 Objects[Index] ? 我都利用它來存一個 Record ,利用 AddObject(String,Object) 來加入,而 Strings[Index] 就變成它的索引,可以利用 IndexOf(String) 自動去找,不用自己寫程式 很方便說... 發現了 >< face="Verdana, Arial, Helvetica"> 感謝版主及 Emulator 網友詳細程式的範例, 我會再好好詳細拜讀一下, 另外版主提供的StringList 用法小弟我倒是第一次聽到, 不知是否有更詳細的說明可以參考?
Emulator
一般會員


發表:1
回覆:18
積分:8
註冊:2002-10-17

發送簡訊給我
#7 引用回覆 回覆 發表時間:2002-10-23 11:45:13 IP:211.74.xxx.xxx 未訂閱
TStringList一樣是內建的元件,其操作跟陣列的想法類似, 我蠻常拿來存一次需要存大量筆數的文字資料。 而且不需要考慮傳陣列所遇到的問題,是蠻好用的..:) 其用法請參考Delphi內的Help或Delphi 6 Developer's Guide = Delphi - Emulator =
------
= Delphi - Emulator =
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2002-10-26 16:55:44 IP:203.204.xxx.xxx 未訂閱
引言:
引言: 不知道您有沒有利用過 TStringList 中的 Objects[Index] ? 我都利用它來存一個 Record ,利用 AddObject(String,Object) 來加入,而 Strings[Index] 就變成它的索引,可以利用 IndexOf(String) 自動去找,不用自己寫程式 很方便說... 發現了 >< face="Verdana, Arial, Helvetica"> 感謝版主及 Emulator 網友詳細程式的範例, 我會再好好詳細拜讀一下, 另外版主提供的StringList 用法小弟我倒是第一次聽到, 不知是否有更詳細的說明可以參考?
範例? Delphi 我不會,以 BCB 來說,例如:
struct{
  char   ID[80];
  int    iDATA;
  double dData;
} MyStruct;
以前的作法,可能就要事件配好夠大的記憶體,而在使用上有限制,使用 TStringList (前題是在資料中有個字串,而且該字串很常用到它來搜尋)就不需事件配置,只需
  TStringList *myList=new TStringList;
  MyStruct *pBuf=new MyStruct;
  strcpy(pBuf->ID,"TEST");
  pBuf->iData=1;
  pBuf->dData-100.001;
  myList->Add(AnsiString(pBuf->ID),pBuf);
之後在使用時可以用
  int Index=myList->IndexOf("DEMO");
  if(Index >= 0) // 表示有在這個 List 中
  {
    MyStruct *pBuf=(MyStruct *)myList->Items[Index];
    // 看您要如何處理這個找到的內容或是要 Delete(Index) 也行
  }
沒空更新的網頁...
C及指標教學,計算機概論,資訊管理導論... http://coolsite.to/dllee 介紹Shells,LiteStep,GeoShell.... http://coolsite.to/ushells
------
http://www.ViewMove.com
系統時間:2024-05-09 8:42:34
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!