[問題] 物件中的變數成員是否會被安排在連續記 …

看板C_and_CPP作者時間14年前 (2011/09/22 15:15), 編輯推噓4(4027)
留言31則, 8人參與, 最新討論串1/2 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) C++ 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) N 問題(Question): 假設我有一個class長成下面這樣: class MyClass { public: MyClass(); private: char Val_1; char Val_2; char Val_3; ... char Val_N; }; 請問我可以認為Val_1~Val_N是一塊連續的記憶體空間嗎? 目前做了N=6的測試發現是如此,但我無法確定是否在任何環境下(編譯器、OS等)都能得 到相同結果。 餵入的資料(Input): N 預期的正確結果(Expected Output): N 錯誤結果(Wrong Output): N 程式碼(Code):(請善用置底文網頁, 記得排版) N 補充說明(Supplement): 回diabloevagto: 我在做的東西是檔案分析,比方說使用者選擇一個音樂檔,檔頭會包含一些資訊,比方 說檔案大小、格式、聲道數、取樣頻率、取樣深度...等,所以我建立了一個class希望 把這些資訊包起來: class FileAnalysis { public: FileAnalysis(); bool OpenFile(string); private: unsigned char Size[4]; unsigned char Format[4]; unsigned char Channel[2]; unsigned char SampleRate[2]; unsigned char SampleBit[2]; ... }; 並且我希望在產生物件時,先將這些資訊初始化: FileAnalysis::FileAnalysis() { memset( Size, 0, sizeof(Size)); memset( Format, 0, sizeof(Format)); memset( Channel, 0, sizeof(Channel)); memset( SampleRate, 0, sizeof(SampleRate)); memset( SampleBit, 0, sizeof(SampleBit)); ... } 這麼一來有個問題,當所要包入的資訊越來越多的時候,建構函式就越來越可怕, 為了不讓程式變成世界奇觀,我想應該有某種方式能簡化這個程序,所以我才想到 ,如果能確保記憶體是在連續區塊,或許我可以: memset( Size, 0, sizeof(N)); 此時N是資訊佔用的總長度,當然回文中有提到這個方式是錯的,不過可以把資訊再 包成struct再以此方式進行。 謝謝大家提供的一些建議。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 211.72.212.239

09/22 15:16, , 1F
印出來看看阿…應該是不連續
09/22 15:16, 1F

09/22 15:17, , 2F
召喚 F 大
09/22 15:17, 2F

09/22 15:20, , 3F
我有印了,N=6時是連續的,可是我沒辦法確定其他狀況。
09/22 15:20, 3F

09/22 15:24, , 4F
可以問一下你想做什麼嗎
09/22 15:24, 4F

09/22 15:25, , 5F
請詳讀#1EPPULmS
09/22 15:25, 5F

09/22 15:25, , 6F
欸不對 #1EPPULmS講的好像是struct...
09/22 15:25, 6F

09/22 15:30, , 7F
回priv: 如果記憶體是連續空間,我想用memset來一次初始
09/22 15:30, 7F

09/22 15:31, , 8F
化所有變數,因為目前的情況不適合用陣列。
09/22 15:31, 8F

09/22 15:33, , 9F
回shadow0326: 謝謝你的建議,雖然他寫不太適合初學者
09/22 15:33, 9F

09/22 15:34, , 10F
但我會盡可能去讀讀看。
09/22 15:34, 10F

09/22 15:40, , 11F
那篇是在講純C,在你問的問題上和C++可能是不太一樣的事
09/22 15:40, 11F

09/22 15:41, , 12F
純C你可以直接去清除整個struct
09/22 15:41, 12F

09/22 15:41, , 13F
C++如果class/struct裡面不是只有POD的時候就不能這樣惡搞
09/22 15:41, 13F

09/22 15:50, , 14F
至於你的問題,會不會形成連續的空間,答案是不一定
09/22 15:50, 14F

09/22 15:50, , 15F
alignment是偏實作面的東西,要看compiler怎麼去定
09/22 15:50, 15F

09/22 15:57, , 16F
就經驗來說如果通通都是char中間應該不會有多餘的padding
09/22 15:57, 16F

09/22 15:57, , 17F
如果是別的type就不是這樣了
09/22 15:57, 17F

09/22 15:57, , 18F
但是我沒辦法幫你掛保證說所有的compiler/os
09/22 15:57, 18F

09/22 15:57, , 19F
都不會在char和char中間塞padding
09/22 15:57, 19F

09/22 16:09, , 20F
謝謝你,既然有風險我就不會這樣做了,我會再想想看有
09/22 16:09, 20F

09/22 16:10, , 21F
沒有其他的安全作法,來達到相同的功能。
09/22 16:10, 21F

09/22 16:24, , 22F
不然你可以考慮把這些變數再用一個struct包起來
09/22 16:24, 22F

09/22 16:24, , 23F
這樣memset清struct的時候就不會清掉char以外的東西
09/22 16:24, 23F

09/22 16:25, , 24F
是否方便把問題丟上來,大家一起討論?
09/22 16:25, 24F
※ 編輯: icetofux 來自: 211.72.212.239 (09/22 16:53)

09/22 16:47, , 25F

09/22 17:01, , 26F
基本上你要用一些編譯器指令去掉padding
09/22 17:01, 26F

09/22 17:03, , 27F
不過假如不是用2進位的方式讀資料進來, 用STL容器+ptr
09/22 17:03, 27F

09/22 17:04, , 28F
to member應該可行
09/22 17:04, 28F

09/22 17:38, , 29F
我的想法是自訂一個class用來處理char.
09/22 17:38, 29F

09/22 17:38, , 30F
09/22 17:38, 30F

09/22 17:39, , 31F
想更改已有的系統.這方法問題很大
09/22 17:39, 31F
文章代碼(AID): #1EUk1_XP (C_and_CPP)
文章代碼(AID): #1EUk1_XP (C_and_CPP)