作者icetofux ()
看板C_and_CPP
標題[問題] 物件中的變數成員是否會被安排在連續記憶體區塊
時間Thu Sep 22 15:15:09 2011
開發平台(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
推 wwf1310:印出來看看阿…應該是不連續 09/22 15:16
推 LPH66:召喚 F 大 09/22 15:17
→ icetofux:我有印了,N=6時是連續的,可是我沒辦法確定其他狀況。 09/22 15:20
→ priv:可以問一下你想做什麼嗎 09/22 15:24
→ shadow0326:欸不對 #1EPPULmS講的好像是struct... 09/22 15:25
→ icetofux:回priv: 如果記憶體是連續空間,我想用memset來一次初始 09/22 15:30
→ icetofux:化所有變數,因為目前的情況不適合用陣列。 09/22 15:31
→ icetofux:回shadow0326: 謝謝你的建議,雖然他寫不太適合初學者 09/22 15:33
→ icetofux:但我會盡可能去讀讀看。 09/22 15:34
→ priv:那篇是在講純C,在你問的問題上和C++可能是不太一樣的事 09/22 15:40
→ priv:純C你可以直接去清除整個struct 09/22 15:41
→ priv:C++如果class/struct裡面不是只有POD的時候就不能這樣惡搞 09/22 15:41
→ priv:至於你的問題,會不會形成連續的空間,答案是不一定 09/22 15:50
→ priv:alignment是偏實作面的東西,要看compiler怎麼去定 09/22 15:50
→ priv:就經驗來說如果通通都是char中間應該不會有多餘的padding 09/22 15:57
→ priv:如果是別的type就不是這樣了 09/22 15:57
→ priv:但是我沒辦法幫你掛保證說所有的compiler/os 09/22 15:57
→ priv:都不會在char和char中間塞padding 09/22 15:57
→ icetofux:謝謝你,既然有風險我就不會這樣做了,我會再想想看有 09/22 16:09
→ icetofux:沒有其他的安全作法,來達到相同的功能。 09/22 16:10
→ priv:不然你可以考慮把這些變數再用一個struct包起來 09/22 16:24
→ priv:這樣memset清struct的時候就不會清掉char以外的東西 09/22 16:24
→ diabloevagto:是否方便把問題丟上來,大家一起討論? 09/22 16:25
※ 編輯: icetofux 來自: 211.72.212.239 (09/22 16:53)
→ loveme00835:基本上你要用一些編譯器指令去掉padding 09/22 17:01
→ loveme00835:不過假如不是用2進位的方式讀資料進來, 用STL容器+ptr 09/22 17:03
→ loveme00835:to member應該可行 09/22 17:04
→ angleevil:我的想法是自訂一個class用來處理char. 09/22 17:38
→ angleevil:想更改已有的系統.這方法問題很大 09/22 17:39