2010-11-01 56 views
-1

下面的代碼按預期工作奇效:用的sizeof

template <typename T> 
inline char* Utils::PushData(char* destination, T data) 
{ 
    memcpy(destination, &data, sizeof(data)); 
    destination += sizeof(T); 
    return destination; 
} 

然而,當我使用這個:

template <typename T> 
inline char* Utils::PushData(char* destination, T data) 
{ 
    memcpy(destination, &data, sizeof(T)); 
    destination += sizeof(T); 
    return destination; 
} 

模型我的建築被搞砸。爲什麼會發生?當然sizeof(T)sizeof(data)應該是一樣的吧?或者我誤解了sizeof實際上獲得的大小?

編輯

我是不是真的太這個人打擾,只是覺得很奇怪。我正在使用memcpy,因爲我需要確保我的數據充滿了填充,我也相信我的自我(唯一會使用此代碼的人,除非我決定繼續使用它)知道僅在基本類型中使用它,而且我甚至不直接調用這個函數,我會調用一個函數,以一種更有意義的方式從調用位置獲取數據。我會打電話使用這樣的模板功能...

inline char* Utils::PushXYZ(char* destination, float xValue, float yValue, float zValue) 
{ 
    destination = PushData<float>(destination, xValue); 
    destination = PushData<float>(destination, yValue); 
    return PushData<float>(destination, zValue); 
} 
+7

'sizeof(T)'和'sizeof(data)'的確應該是一樣的。什麼特別讓你覺得他們不是? (你可以縮小它從「變化破壞了什麼」?) – aschepler 2010-11-01 19:38:21

+0

目的地得到分配? – 2010-11-01 19:53:36

+0

即使第一個代碼片段使用sizeof(T)('destination + = sizeof(T)'line)。如果我們知道哪種數據類型導致問題,回答這個問題會更容易。 – 2010-11-01 20:12:58

回答

2

當然sizeof(T)和sizeof(數據)應該是一樣的吧?或者我誤解了sizeof實際上是多少?

情況並非一定如此。當應用於data

template<typename T> void f(T data); 
int main() { f<char[1]>(0); } 

當應用於T這將產生sizeof(char[1])sizeof(char*):考慮這一個。根據你的代碼,你可能會有奇怪的實例化你的模板,這可能導致這種情況。

+0

天哪。所以,如果你不在算法中使用'iterator_traits',人們可以'char g [] =「hi there」; std :: for_each (g,g + 8,Whatever());'。這是......特別的。 – 2010-11-09 00:00:22

2

在c + +中使用memcpy是一個非常糟糕的主意。

你知道如果你memcpy具有虛擬方法的類的對象會發生什麼?如果memcpy類像vector和string那樣會發生什麼?如果你是幸運的 - 核心轉儲。

btw你是怎麼使用這個功能的?什麼地方出了錯? etc 如果可能發佈一個最小的可編譯示例

+0

好吧,我同意有私人堆存儲的對象的memcpy是壞的,但我沒有看到虛擬方法如何發揮(除了使對象具有私有堆存儲與否)不太清楚。通常情況下,擁有虛擬方法意味着有一個或多個vtbl指針,它在構造時設置,指向一個常量表,並且不會改變對象的生命週期。我看不到如何複製這些指針(因爲它們不指向堆分配塊)會破壞事情。 – 2010-11-01 20:09:56

+1

@Mike DeSimone:更合適的是,如果memcpy sizeof(T)字節,從T派生的任何類型將以非常糟糕的方式切片,並且虛擬函數將立即崩潰,因爲動態類型爲:T但數據只是T. – Puppy 2010-11-01 20:26:34

+2

@Mike @Dead:簡單來說,非POD類型不能被視爲一個位序列,這樣做會導致UB。 – GManNickG 2010-11-01 20:53:42

2

如果sizeof(T)== sizeof(data),它通常應該檢查調試器。不是100%肯定會發生什麼,如果T是一個參考類型,但我認爲sizeof(U&)將不會像sizeof()通過參數U &類型。

+0

如果您傳遞該函數的引用,則sizeof將返回正確的值(除非有問題的編譯器)。從原始文章中的代碼創建示例很容易(只需將數據大小和T輸出到標準輸出)。 – 2010-11-01 19:54:18

1

memcpy()不會買你什麼東西。使用數組或向量。

你正在推進destination指針sizeof(data)。如果使用數組,則從一個條目到下一個條目的距離是sizeof(data)。沒有不同。

如果在data的末尾沒有填充,則沒有浪費的空間。如果最後有填充,它就是數據結構的一部分,並將包含在sizeof()中。如果您想節省內存,請查看編譯器選項以在類中打包信息。

如果您使用的是標準類型,例如編輯中的float,則無論採用何種方式都不會浪費內存。

即使在編輯過程中,您還沒有提供任何測試方法或獲得的結果的示例,因此沒有人能夠爲您提供幫助。