2011-01-09 15 views
7

पर विचार करें निम्नलिखित कोड:समझौता सी ++ struct आकार

struct CExample { 
    int a; 
}    

int main(int argc, char* argv[]) { 

    CExample ce1; 
    CExample ce2; 

    cout << "Size:" << sizeof(ce1) << " Address: " << &ce1 << endl; 
    cout << "Size:" << sizeof(ce2) << " Address: " << &ce2 << endl; 

    CExample ceArr[2]; 
    cout << "Size:" << sizeof(ceArr[0])<< " Address: "<< &ceArr[0] <<endl; 
    cout << "Size:" << sizeof(ceArr[1])<< " Address: "<< &ceArr[1] <<endl; 

    return 0; 
} 

आउटपुट उदाहरण:
CE1: आकार = 4, पता: 0039FAA0
CE2: आकार = 4, पता: 0039FA94
ceArr [0] : आकार = 4, पता: 0039FA84
ceArr [1]: आकार = 4, पता: 0039FA88

कोड के साथ

वहाँ पहले दो वस्तुओं के पते (CE1 और CE2), लेकिन जो 12-बाइट है वहाँ केवल 4-बाइट अंतर शर्त है सरणी में वस्तुओं को बुनाई।

मैंने सोचा कि डेटा-संरेखण के मुद्दे के साथ कुछ करना होगा, लेकिन मैं अभी भी स्टंप हूं। कोई विचार वास्तव में यहां क्या चल रहा है?

+2

ऊपर के उत्पादन में क्या है? कोड को कोड में भी पोस्ट करना? –

उत्तर

15

क्योंकि किसी सरणी में ऑब्जेक्ट्स को संगत होने की आवश्यकता होती है। ऑब्जेक्ट्स लगातार स्टैक पर घोषित ऑब्जेक्ट्स (स्रोत कोड में, मशीन नहीं) नहीं हैं [संगत होने की आवश्यकता है], हालांकि वे हो सकते हैं।

+1

ठीक है, वे ** ** हो सकते हैं, लेकिन वे ** आवश्यक ** नहीं हैं। –

+0

@ बिली यही मैंने कहा था। –

+0

क्षमा करें .. गलत पढ़ाओ। दूसरी वाक्य, स्वयं द्वारा पढ़ी जाती है, ऐसा लगता है कि वे कभी भी संगत नहीं होते हैं। क्षमा करें :( –

6

मानक इस बारे में कुछ भी नहीं कहता है। कंपाइलर आइटम के बीच जो भी पैडिंग चाहता है उसे सम्मिलित करने के लिए स्वतंत्र है।

(यदि मुझे लगता है कि करने के लिए किया था, मुझे लगता है कि चाहते हैं कि आपके संकलक डिबग मोड में ढेर संरक्षण/कनारी के कुछ फार्म को लागू करता है (और है कि आप डिबग मोड) में संकलन कर रहे हैं)

+0

संभव है कि यह अस्थायी वस्तुओं की जगह आरक्षित कर रहा है, (या शायद एक ईस्टर अंडे है? –

+0

हाँ आप सही हैं! मैंने रिलीज मोड में संकलन करने की कोशिश की है और यह काम करता है जैसा कि मैंने उम्मीद की थी! – kiokko89

0

कारण यह है कि, पर है अधिकांश आर्किटेक्चर, unaligned लोड धीमे हैं। अच्छी व्याख्या के लिए data structure alignment पर विकिपीडिया प्रविष्टि देखें। कंपाइलर डेटा शब्द की शुरुआत में आपके प्रत्येक डेटा संरचनाओं को रखता है। हालांकि, सरणी में, वस्तुओं को स्मृति में संयोजित रखा जाता है (जैसा कि सी ++ मानक आवश्यक है)।

+2

मुझे कोई वास्तुकला नहीं है जिसके लिए 12 बाइट सीमाओं पर संरेखण की आवश्यकता है। क्या आप किसी के बारे में जानते हैं? –

+0

नहीं। ओपी ने आउटपुट (आईआईआरसी) पोस्ट नहीं किया था, जो दिखाता है कि यह एक संरेखण मुद्दा नहीं है। मैंने पोस्टर माना मतलब 12 बाइट्स = 16 बाइट मूल ऑब्जेक्ट से 4 बाइट घटाते हैं। जब मैंने इसे अपने मैक पर संकलित किया, तो मुझे 16 बाइट्स अंतर की उम्मीद थी। @ kiokko89 - यह महत्वपूर्ण नहीं है, लेकिन आप किस कंपाइलर/प्लेटफॉर्म का उपयोग कर रहे हैं? – EmeryBerger

+0

मैं एक एक्स 64 मशीन के साथ विजुअल स्टूडियो कंपाइलर का उपयोग कर रहा हूं (मेरी खराब अंग्रेजी के लिए खेद है) – kiokko89

1

कंपाइलर न केवल आपके स्थानीय चर रखने के लिए स्टैक का उपयोग करता है - यह तर्क के लिए उदाहरण के लिए इसका उपयोग करता है, और कुछ ओवरहेड std::cout के कारण होता है। शायद यह है कि आपके चर के बीच अतिरिक्त जगह का उपयोग किया जाता है।

आप इसके बजाय अपने चर static, इस तरह करते हैं:

static CExample ce; 
static CExample ce2; 

static CExample ceArr[2]; 

... चर बीएसएस स्मृति में बजाय रखा जाएगा, और संरेखण अधिक होने की संभावना हो जाएगा कि आप क्या उम्मीद करते हैं।

कारण है कि सरणियों भरे होते हैं, और अलग-अलग आइटम नहीं हैं, अन्य उत्तर से स्पष्ट किया जाता है ...

संबंधित मुद्दे