結構陣列宣告問題 |
尚未結案
|
renth555
一般會員 發表:32 回覆:65 積分:19 註冊:2003-02-17 發送簡訊給我 |
|
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
引言: typedef struct{ AnsiString GSET; AnsiString NAME; }DAT; int X=50; DAT AAA[X]; 我的問題在於 [X] 因我還不知結構確定值 要程式跑後才知 X=多少 請問這樣的方法有解嗎renth555 你好: 請參考以下的做法 < class="code"> #include "StrUtils.hpp" // 宣告 struct (建議儘量別使用 AnsiString 宣告在 struct 裡面,在某些應 // 用的情況之下會有問題的;建議改用宣告佔有實體記憶體的 char array) typedef struct _MYSTRUCT { char szGSET[64]; char szNAME[64]; } MYSTRUCT; // 假設已經動態取得 iX=50 int iX=50; // 宣告 MYSTRUCT 的指標 MYSTRUCT *pMyStruct=NULL; // 動態配置記憶體給 MYSTRUCT 的指標 pMyStruct=(MYSTRUCT*)new BYTE[iX*sizeof(MYSTRUCT)]; // 養成好習慣,先將動態配置的記憶體每個 BYTE 歸零 ZeroMemory(pMyStruct, iX*sizeof(MYSTRUCT)); // 設定 struct 的值 for(int i=0; i
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
tomlee
一般會員 發表:5 回覆:14 積分:18 註冊:2003-10-11 發送簡訊給我 |
引言:引言: typedef struct{ AnsiString GSET; AnsiString NAME; }DAT; int X=50; DAT AAA[X]; 我的問題在於 [X] 因我還不知結構確定值 要程式跑後才知 X=多少 請問這樣的方法有解嗎renth555 你好: 請參考以下的做法 < class="code"> #include "StrUtils.hpp" // 宣告 struct (建議儘量別使用 AnsiString 宣告在 struct 裡面,在某些應 // 用的情況之下會有問題的;建議改用宣告佔有實體記憶體的 char array) typedef struct _MYSTRUCT { char szGSET[64]; char szNAME[64]; } MYSTRUCT; // 假設已經動態取得 iX=50 int iX=50; // 宣告 MYSTRUCT 的指標 MYSTRUCT *pMyStruct=NULL; // 動態配置記憶體給 MYSTRUCT 的指標 pMyStruct=(MYSTRUCT*)new BYTE[iX*sizeof(MYSTRUCT)]; // 養成好習慣,先將動態配置的記憶體每個 BYTE 歸零 ZeroMemory(pMyStruct, iX*sizeof(MYSTRUCT)); // 設定 struct 的值 for(int i=0; i 直接改成這樣就好了: struct DAT { AnsiString GSET; AnsiString NAME; }; 用標準函式庫的 vector<> ,就可以解決你的問題。 vector |
renth555
一般會員 發表:32 回覆:65 積分:19 註冊:2003-02-17 發送簡訊給我 |
typedef struct{
AnsiString aaa;
AnsiString bbb;
}DAT; int X=50;
DAT *z=NULL;
z =(DAT*)new BYTE[X*sizeof(DAT)]; //動態配置記憶體指標
ZeroMemory(z,X*sizeof(DAT)); //動態配置的記憶體每個 BYTE 歸零
z[1].aaa="abc";
z[0].aaa="xyz"; 這樣真的就可以了謝謝 但tomlee 前輩這樣宣告不會過為什麼 pMyStruct = new BYTE[iX*sizeof MYSTRUCT]; RaynorPao 前輩可以詳細為我解說下面語法意思嗎 new BYTE[X*sizeof(DAT)] ----> 比如結果 BYTE[50x10]
(DAT*) ------> 強制轉換 (不懂) z=???? z =(DAT*)new BYTE[X*sizeof(DAT)]; //動態配置記憶體指標
ZeroMemory(z,X*sizeof(DAT)); //動態配置的記憶體每個 BYTE 歸零
|
renth555
一般會員 發表:32 回覆:65 積分:19 註冊:2003-02-17 發送簡訊給我 |
void __fastcall TForm1::Button1Click(TObject *Sender)
{ typedef struct{
AnsiString aaa;
AnsiString bbb;
}DAT; int X=50;
DAT *z=NULL;
z =(DAT*)new BYTE[X*sizeof(DAT)];
ZeroMemory(z,X*sizeof(DAT));
z[0].aaa="abc";
z[1].aaa="xyz";
z[100].aaa="vvvv"; ----------------------->為什麼可以 ShowMessage(z[100].aaa);
delete z;
} 這樣也可以 這樣就不可以
delete [] z;
|
taishyang
站務副站長 發表:377 回覆:5490 積分:4563 註冊:2002-10-08 發送簡訊給我 |
|
RaynorPao
版主 發表:139 回覆:3622 積分:7025 註冊:2002-08-12 發送簡訊給我 |
renth555 你好:
引言: typedef struct{ AnsiString aaa; AnsiString bbb; }DAT; int X=50; DAT *z=NULL; z =(DAT*)new BYTE[X*sizeof(DAT)]; //動態配置記憶體指標 ZeroMemory(z,X*sizeof(DAT)); //動態配置的記憶體每個 BYTE 歸零 z[1].aaa="abc"; z[0].aaa="xyz"; 這樣真的就可以了謝謝 但tomlee 前輩這樣宣告不會過為什麼 pMyStruct = new BYTE[iX*sizeof MYSTRUCT];(1)因為 pMyStruct 的型態被宣告為 MYSTRUCT 的指標,因此如果這樣子寫,在 編譯的時候會被 compiler 視為不合法的語法,所以,才會需要強制轉型為 MYSTRUCT 的指標,如下: pMyStruct=(MYSTRUCT*)new BYTE[iX*sizeof(MYSTRUCT)];RaynorPao 前輩可以詳細為我解說下面語法意思嗎 new BYTE[X*sizeof(DAT)] ----> 比如結果 BYTE[50x10] (DAT*) ------> 強制轉換 (不懂) z=????(2)有關這一點已經在 (1) 中說明,其實那一行也可以這樣子寫,而且這兩種寫 法的意義跟結果是一模一樣的 (請你仔細、用心研究),如下: pMyStruct=new MYSTRUCT[iX]; 可以這樣子解釋: 為 pMyStruct 宣告一塊記憶體,而這塊記憶體包括 10 個 MYSTRUCT (陣列),pMyStruct 指向第一個 (index=0) 記憶體位置,所以: (a)當這樣寫的時候 pMyStruct[0] 是 access 第 1 個 (index=0) MYSTRUCT (b)當這樣寫的時候 pMyStruct[n-1] 是 access 第 n 個 MYSTRUCT (3)如果以上的解釋方式,還不能夠讓你了解的話,我就再另外舉一個例子,以 下的兩種寫法 (標示為綠色) 其意義跟結果是一模一樣的 int iY=50; int *pi=NULL; pi=new int[iY]; // pi=(int*)new BYTE[iY*sizeof(int)]; // ...Do something... delete pi; 看出來了嗎?? 目前 Win32 的 compiler 對於 int 這個型態的預設佔記憶體 數都是 4 Bytes,所以當我這樣宣告的時候 (a)pi=new int[iY]; 總共宣告了 4*50=200 Bytes 給 pi 這個 int 指標 (b)pi=(int*)new BYTE[iY*sizeof(int)]; 總共宣告了 1*50*4=200 Bytes 給 pi 這個 int 指標 (經過強制轉型,把 BYTE 指標轉成 int 指標)z =(DAT*)new BYTE[X*sizeof(DAT)]; //動態配置記憶體指標 ZeroMemory(z,X*sizeof(DAT)); //動態配置的記憶體每個 BYTE 歸零 引言: void __fastcall TForm1::Button1Click(TObject *Sender) { typedef struct{ AnsiString aaa; AnsiString bbb; }DAT; int X=50; DAT *z=NULL; z =(DAT*)new BYTE[X*sizeof(DAT)]; ZeroMemory(z,X*sizeof(DAT)); z[0].aaa="abc"; z[1].aaa="xyz"; z[100].aaa="vvvv"; ----------------------->為什麼可以-- Enjoy Researching & Developing -- 發表人 - RaynorPao 於 2003/10/27 21:13:24(4)為什麼可以?? 不,那當然不可以,而且是很明顯的錯誤,但是 Windows 為 什麼不會顯示出 Access Violation 的錯誤訊息呢?? 先建議你把以上的程式 碼改成以下這個樣子執行看看 typedef struct _DAT { AnsiString aaa; AnsiString bbb; } DAT; Memo1->Lines->Clear(); int X=50; DAT *z=NULL; z=new DAT[X]; ZeroMemory(z, X*sizeof(DAT)); for(int i=0; i<100; i ) { z[i].aaa=IntToStr(i); z[i].bbb=IntToStr(i); Memo1->Lines->Add(z[i].aaa ", " z[i].bbb); } delete z; 當你執行的時候,是不是 Access Violation 馬上跑出來了呢?? 其實原因很 簡單,這是 Windows 作業系統的「防呆裝置」,也就是說,當發生了很小的 Access Violation 的時候,Windows 作業系統會概括性承受,尤其是 2000 以後的作業系統,原本這應該是 M$ 的一番美意,卻害了不少程式設計師, 以為這樣寫是正確的,但事實卻是相反的,而且有一點要特別注意,那就是 這樣子寫並不是完全不會出現 Access Violation 的錯誤訊息 (有時候會出 現,有時候不會出現,造成了程式設計師難抓的大 bug);一旦發生了比較嚴 重 (大量) 記憶體違規存取的時候,Windows 才會馬上、立即顯示 Access Violation 的錯誤訊息,當然,這會導致 Application 被 Windows 作業系 統強制關閉,所以,要儘量小心避免這種錯誤,當然,最好的方法還是在每 個函式寫好之後,記得要做「迴圈」及「多執行緒」測試,才能夠找出這些 潛在且致命的程式碼。有的時候,我們常聽到某些已經出貨 (上線) 的系統 不太穩定 (有的時候會掛點),其實部分的原因,都是上述的情況所造成的ShowMessage(z[100].aaa); delete z; } 這樣也可以 這樣就不可以 delete [] z;
------
-- 若您已經得到滿意的答覆,請適時結案!! -- -- 欲知前世因,今生受者是;欲知來世果,今生做者是 -- -- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 -- |
renth555
一般會員 發表:32 回覆:65 積分:19 註冊:2003-02-17 發送簡訊給我 |
|
tomlee
一般會員 發表:5 回覆:14 積分:18 註冊:2003-10-11 發送簡訊給我 |
引言:引言: typedef struct{ AnsiString GSET; AnsiString NAME; }DAT; int X=50; DAT AAA[X]; 我的問題在於 [X] 因我還不知結構確定值 要程式跑後才知 X=多少 請問這樣的方法有解嗎renth555 你好: 請參考以下的做法 < class="code"> #include "StrUtils.hpp" // 宣告 struct (建議儘量別使用 AnsiString 宣告在 struct 裡面,在某些應 // 用的情況之下會有問題的;建議改用宣告佔有實體記憶體的 char array) typedef struct _MYSTRUCT { char szGSET[64]; char szNAME[64]; } MYSTRUCT; // 假設已經動態取得 iX=50 int iX=50; // 宣告 MYSTRUCT 的指標 MYSTRUCT *pMyStruct=NULL; // 動態配置記憶體給 MYSTRUCT 的指標 pMyStruct=(MYSTRUCT*)new BYTE[iX*sizeof(MYSTRUCT)]; // 養成好習慣,先將動態配置的記憶體每個 BYTE 歸零 ZeroMemory(pMyStruct, iX*sizeof(MYSTRUCT)); // 釋放記憶體 delete pMyStruct; -- Enjoy Researching & Developing -- 關於動態配置的問題,C 的標準作法應該是這樣: class DATA { AnsiString GSET; AnsiString NAME; }; DATA *Data = new DATA[ix]; //... delete [] Data; 或者用標準函式庫中的 vector 來作: vector Data; // 執行期可以動態設定大小: Data.reset(ix); // 或者一個一個加進去: for (int i=0; i |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |