2014-02-28 41 views
0

下面的程序使用gcc編譯並在32位架構上執行時會返回16個字節。我想知道爲什麼它會返回,因爲它既沒有使用長雙成員,也沒有在64位機器上運行,也沒有定義虛函數來獲取額外的內存字節,並且在計算double時的大小以及int數據成員,結果大約有12個字節。那麼爲什麼這16個字節值?爲什麼這個C++程序返回16個字節?

class A { 
public: 
    void* data; 
}; 
void* operator new (size_t sz, A& obj) { 
    printf("Custom operator new called for %d bytes\n", sz); 
    return obj.data; 
} 
class foo { 
public: 
    double a; 
    int x; 
    foo() { printf("foo constructor called (this=%p)\n", this); } 
}; 
int main() { 
    A obj; 
    obj.data = malloc(sizeof(foo)); 
    printf("Allocator data: %p\n", obj.data); // Allocator data: 0x4601a8 
    foo *f = new (obj) foo; // Custom operator new called for **16 bytes** 
             // foo constructor called (this=0x4601a8) 
    printf("foo allocated at %p\n", f); // foo allocated at 0x4601a8 
} 
+1

結構物體內可能存在無名填充 – michaeltang

+0

取決於您的默認填充 - 1,2或4個字節的填充,您將得到12.使用8或16字節填充,您將得到16. – cup

回答

4

4字節在foo結束作爲填充溶液。這通常是爲了對齊目的而完成的 - double在您的體系結構上與8字節對齊,因此如果您創建foo的數組,則填充字節將保證成員a已正確對齊。

在班級類型中,不能保證大小等於成員的大小之和。往往不是,它不是。

有一些特殊的編譯器相關標誌可以防止添加填充字節,您可以查看它們。 (pragma pack

+0

是 - 雙 –

0

8 * N,所以4字節填充

可以有結構對象內無名填充,這是在你的情況稱爲 Data_structure_alignment

,雙對準8個字節,所以的sizeof FOO應

0

當我運行代碼,我發現以下幾點:

class A { 
public: 
    void* data; 
}; 
void* operator new (size_t sz, A& obj) { 
    printf("Custom operator new called for %d bytes\n", sz); 
    return obj.data; 
} 
class foo { 
public: 
    double a; 
    int x; 
    foo() { printf("foo constructor called (this=%p)\n", this); } 
}; 
int main() { 
    A obj; 
    obj.data = malloc(sizeof(foo)); 
    printf("Allocator data: %p\n", obj.data); // Allocator data: 0x991d008 
    printf("size of obj: %d\n", sizeof(obj)); // size of obj: 4 
    printf("size of foo: %d\n",sizeof(foo)); // size of foo: 12 
    foo *f = new (obj) foo; // Custom operator new called for **12 bytes** 
             // foo constructor called (this=0x991d008) 
    printf("foo allocated at %p\n", f); // foo allocated at 0x991d008 
} 

我已經添加了兩個附加的打印聲明,這裏的foo尺寸爲12即double + int

+0

填充是系統特定的,所以這不幸沒有幫助。該代碼將在不同的計算機和編譯器上得到不同的結果。 – Lundin

0

這是因爲編譯器應用了內部填充。我們可以通過使用__packed編譯器指令來避免這種情況。

您可以參考以下的職位的理解有關填充

Structure padding and packing

0

考慮data alignment。編譯器將oder中的對象的數據對齊以將它們存儲在內存中,以便CPU可以將它們放入一個負載 - 這僅適用於對齊的數據。這是硬件方面。