2010-05-10 11 views
7

मैं जो का उपयोग करता है एक सामान्य प्रयोजन पुस्तकालय के विकास कर रहा हूँ Win32 के HeapAllocक्या संरेखण HeapAlloc का उपयोग करता है

MSDN Win32 के HeapAlloc के लिए संरेखण की गारंटी देता है उल्लेख नहीं है, लेकिन मैं वास्तव में पता है कि संरेखण इसे इस्तेमाल करता है की जरूरत है, तो मैं बच सकते हैं अत्यधिक पैडिंग

मेरी मशीन (विस्टा, x86) पर, सभी आवंटन 8 बाइट्स पर गठबंधन होते हैं। क्या यह अन्य प्लेटफार्मों के लिए भी सच है?

+6

यदि एमएसडीएन यह नहीं कहता है, तो * कोई गारंटी नहीं है *। यहां तक ​​कि यदि आप 1000 लोगों से पूछते हैं और वे सभी अपनी मशीन पर 8 बाइट निर्धारित करते हैं, तो यह गारंटी नहीं है, और आपको शायद इस पर भरोसा नहीं करना चाहिए। –

+0

मैं उपर्युक्त स्टेटमेंट के साथ सहमत हूं। आप यह देखने के लिए http://blogs.msdn.com/oldnewthing/archive/2007/12/27/6873648.aspx देख सकते हैं कि यह इसके प्रासंगिक है या नहीं। – torak

+1

मैं सहमत हूं, कोई गारंटी नहीं है, लेकिन मैं यहां गारंटी की मांग नहीं कर रहा हूं: मैं अनुभव मांग रहा हूं। मुझे विश्वास है कि माइक्रोसॉफ्ट 8 बाइट्स के नीचे संरेखण को कभी कम नहीं करेगा, क्योंकि डबल अब और पठनीय नहीं होगा। मैं बस यह जानना चाहता हूं कि एम्बेडेड प्लेटफार्मों के लिए भी सच है। – Ondergetekende

उत्तर

2

HeapAlloc समारोह MSDN पेज में संरेखण की गारंटी देता है निर्दिष्ट नहीं है, लेकिन मुझे लगता है कि यह GlobalAlloc है, जो स्मृति 8-बाइट गठबंधन वापस जाने के लिए गारंटी है की एक ही गारंटी होनी चाहिए इच्छुक हूँ (हालांकि भरोसा अनियंत्रित विशेषताओं पर बुराई है); आखिरकार, यह स्पष्ट रूप से कहा गया है कि ग्लोबल/लोकलएलोक हेपअलोक के आसपास सिर्फ रैपर हैं (हालांकि वे गठबंधन स्मृति प्राप्त करने के लिए पहले n बाइट्स को छोड़ सकते हैं - लेकिन मुझे लगता है कि यह बहुत ही असंभव है)।

यदि आप वास्तव में सुनिश्चित करना चाहते हैं, तो ग्लोबल अलाक, या यहां तक ​​कि वर्चुअलअलोक का भी उपयोग करें, जिसका ग्रैन्युलरिटी पृष्ठ ग्रैन्युलरिटी है, जो आमतौर पर 4 केबी (आईआईआरसी) होता है, लेकिन इस मामले में छोटे आवंटन के लिए आप बहुत सारे बर्बाद कर देंगे याद।

वैसे, यदि आप सी ++ नए ऑपरेटर का उपयोग करते हैं, तो आपको निर्दिष्ट प्रकार के लिए स्मृति को गठबंधन करने की गारंटी दी जाती है: यह जाने का तरीका हो सकता है।

1

संरेखण ऐसा होगा कि लौटाया गया पता किसी भी प्रकार के सूचक को डाला जा सकता है। अन्यथा आप अपने आवेदन में स्मृति का उपयोग करने में सक्षम नहीं होंगे।

+0

यदि मैं सही ढंग से आपका उत्तर समझता हूं, तो तथ्य यह है कि लौटाया गया पता किसी भी प्रकार के पॉइंटर पर डाला जा सकता है, आवंटित स्मृति के संरेखण से संबंधित नहीं है। –

+0

@Matteo: यह संबंधित है। यदि इसे किसी प्रकार के टी के लिए गठबंधन नहीं किया गया था, तो 'टी *' पर एक कास्ट अमान्य होगा (यह संकलित होगा, लेकिन यह काम करने की गारंटी नहीं होगी)। इसलिए क्योंकि इसे किसी भी प्रकार से डाला जा सकता है, इसे किसी भी प्रकार के साथ काम करने के लिए कड़ाई से पर्याप्त रूप से गठबंधन किया जाना चाहिए। – jalf

+0

ठीक है, मैं आपके उत्तर को किसी अन्य तरीके से समझ गया, इसलिए मैंने जो भी कहा वह लागू नहीं होने से पहले; फिर भी, ओएस गारंटी नहीं दे सकता कि यह * किसी * प्रकार के लिए गठबंधन है, अन्यथा केवल एक पूर्ण सूचक ठीक होगा :)। संभवतः यह सबसे बड़े प्रकार के लिए काम करने की गारंटी है जिसके लिए आवंटन लिखने वाले लोगों के लिए संरेखण की आवश्यकता होती है (या सबसे बड़े प्रकार के लिए जो संरेखण की आवश्यकता होती है, जो लोग आवंटकों को लिखते हैं वे सीधे समर्थन करने के इच्छुक हैं)। –

3

हैरानी की बात है, गूगल जाता evidence कि HeapAlloc हमेशा SSE-संगत नहीं है:

HeapAlloc() सभी वस्तुओं हमेशा 8-बाइट गठबंधन, कोई फर्क नहीं पड़ता उनके आकार क्या है (लेकिन 16-बाइट है एसएसई के लिए हस्ताक्षर किए गए)।

यह पोस्ट 2008 के मध्य से है, यह सुझाव देते हुए कि हाल ही में विंडोज एक्सपी इस बग से पीड़ित है।

भी http://support.microsoft.com/kb/286470 देखें:

विंडोज ढेर प्रबंधकों (सभी संस्करणों) हमेशा गारंटी है कि ढेर आवंटन एक शुरुआत पता है कि 8-बाइट गठबंधन (64-बिट प्लेटफार्मों संरेखण है पर है 16- बाइट्स)।

+0

हां, एसएसई प्रकार एक प्रकार का छाया अस्तित्व जीते हैं जहां उनके संरेखण को आवंटन कार्यों द्वारा शायद ही कभी सम्मानित किया जाता है। मुझे यकीन नहीं है कि क्यों, लेकिन यह विंडोज और लिनक्स दोनों पर मामला प्रतीत होता है। डिफ़ॉल्ट रूप से, आपको 8 बाइट्स से बेहतर संरेखण गारंटी नहीं मिलती है। – jalf

+0

@jalf: अजीब! मुझे 1 999 में याद आया जब अल्टीवीक पेश किया गया था, ऐप्पल ने तुरंत 16-बाइट संरेखण के लिए अपने आवंटन कार्यों 'न्यूपीआरटी' और 'न्यूहैंडल' को दोबारा निर्दिष्ट किया। ऐसा नहीं है कि आप पुराने सॉफ्टवेयर को इस तरह से तोड़ दें! – Potatoswatter

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