2010-10-22 18 views

उत्तर

6

Alignment आवश्यकताएं निर्दिष्ट करती हैं कि किस प्रकार के पते को ऑफसेट को असाइन किया जा सकता है। यह पूरी तरह से कार्यान्वयन-निर्भर है, लेकिन आम तौर पर शब्द के आकार पर आधारित होता है। उदाहरण के लिए, कुछ 32-बिट आर्किटेक्चर के लिए सभी int चर की आवश्यकता होती है जो चार में से एक पर शुरू होती है। कुछ आर्किटेक्चर पर, संरेखण आवश्यकताओं पूर्ण हैं। दूसरों पर (उदा। X86) उन्हें फ़्लोटिंग केवल प्रदर्शन दंड के साथ आता है।

malloc किसी भी संरेखण आवश्यकता के लिए उपयुक्त पता वापस करने की आवश्यकता है। दूसरे शब्दों में, लौटाया गया पता किसी भी प्रकार के सूचक को सौंपा जा सकता है। C99 §7.20.3 (मेमोरी प्रबंधन कार्यों) से:

सूचक लौटे अगर आवंटन सफल होता उपयुक्त रूप से गठबंधन किया है, ताकि यह वस्तु के किसी भी प्रकार के लिए सूचक को सौंपा जा सकता है और उसके बाद का उपयोग करने के लिए इस्तेमाल आवंटित स्थान में ऐसी वस्तु या ऐसी ऑब्जेक्ट्स की एक सरणी ( तक स्थान स्पष्ट रूप से हटा दिया गया है)।

1

आप विशेष स्मृति alignemnt जरूरतों है, तो (विशेष रूप से हार्डवेयर या पुस्तकालयों के लिए), तुम बाहर इस तरह के _aligned_malloc() और memalign() रूप में गैर-पोर्टेबल मेमोरी allocators देख सकते हैं। इन्हें आसानी से "पोर्टेबल" इंटरफ़ेस के पीछे सारणित किया जा सकता है, लेकिन दुर्भाग्यवश गैर-मानक हैं।

43

मान लीजिए कि आपके पास संरचना है।

struct S { 
    short a; 
    int b; 
    char c, d; 
}; 

संरेखण के बिना, यह इस (एक 32-बिट संरचना कल्पना करते हुए) की तरह स्मृति में बाहर रखी जाएगी:

0 1 2 3 4 5 6 7 
|a|a|b|b|b|b|c|d| bytes 
|  |  | words 

समस्या यह है कि कुछ सीपीयू आर्किटेक्चर पर, अनुदेश एक 4 लोड करने के लिए है स्मृति से -बीटी पूर्णांक केवल शब्द सीमाओं पर काम करता है। तो आपके कार्यक्रम को अलग-अलग निर्देशों के साथ b के प्रत्येक आधे भाग लेना होगा।

लेकिन अगर स्मृति के रूप में बाहर रखी गई थी:

0 1 2 3 4 5 6 7 8 9 A B 
|a|a| | |b|b|b|b|c|d| | | 
|  |  |  | 

फिर b के लिए पहुँच सीधा हो जाता है। (नुकसान यह है कि पैडिंग बाइट्स की वजह से अधिक मेमोरी की आवश्यकता होती है।)

विभिन्न डेटा प्रकारों में अलग-अलग संरेखण आवश्यकताएं होती हैं। char के लिए 1-बाइट गठबंधन, short 2-बाइट संरेखित होने के लिए, और 4-बाइट प्रकार (int, float, और 32-बिट सिस्टम पर पॉइंटर्स) 4-बाइट संरेखित होने के लिए आम है।

malloc सी मानक द्वारा किसी पॉइंटर को वापस करने के लिए आवश्यक है जो किसी भी डेटा प्रकार के लिए ठीक से गठबंधन किया गया है।

x86-64 पर glibc malloc 16-बाइट-गठबंधन पॉइंटर्स लौटाता है।

+0

वास्तव में बहुत अच्छी व्याख्या है। – AnyOneElse

+0

अच्छा स्पष्टीकरण। – hagrawal

+0

क्षमा करें, मैं नहीं करता हूं कि आपका क्या मतलब है "चार के लिए 1-बाइट गठबंधन होना आम है, 2-बाइट गठबंधन होना चाहिए, और 4-बाइट प्रकार"। –

1

malloc() प्रलेखन कहते हैं:

[...] the allocated memory that is suitably aligned for any kind of variable. 

कौन-सी सबसे सब कुछ सी में आप करते हैं/C++ के लिए सच है।हालांकि, जैसा कि दूसरों द्वारा इंगित किया गया है, कई विशेष मामले मौजूद हैं और एक विशिष्ट संरेखण की आवश्यकता है। उदाहरण के लिए, इंटेल प्रोसेसर 256 बिट प्रकार का समर्थन करते हैं: __m256, जिसे निश्चित रूप से malloc() द्वारा ध्यान में नहीं लिया जाता है।

इसी प्रकार, यदि आप डेटा के लिए एक स्मृति बफर पृष्ठांकित किया जा रहा है कि (mmap() द्वारा लौटाए गए पतों के समान, आदि) आवंटित करना चाहते है तो आप एक संभवतः बहुत बड़ी संरेखण जो स्मृति का एक बहुत बर्बाद होता अगर malloc() था की जरूरत है बफर वापस लौटने के लिए हमेशा इस सीमाओं के साथ गठबंधन।

int posix_memalign(void **memptr, size_t alignment, size_t size); 

यह सबसे हाल का समारोह है कि एक ऐसी जरूरतों के लिए उपयोग करना चाहता है:

लिनक्स या अन्य यूनिक्स प्रणालियों के तहत, मैं तुम्हें posix_memalign() फ़ंक्शन का उपयोग करें सुझाव देते हैं।

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