Alignment और Splitting
ब्लॉक को उपयोग योग्य और व्यवस्थित बनाएँ।
Alignment और Splitting, CoddyKit पर C Academy का एक निःशुल्क पाठ है। यह 4 में से 4वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह C Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। C Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
संरेखण क्यों महत्वपूर्ण है
हर प्रकार की एक संरेखण आवश्यकता होती है: उसका पता दो की किसी घात के गुणज के बराबर होना चाहिए। double के लिए सामान्यतः 8-बाइट संरेखण आवश्यक होता है।
क्योंकि malloc को यह पता नहीं होता कि आप उसमें क्या रखेंगे, इसलिए उसे सबसे कड़े प्रकार के लिए संरेखित पॉइंटर लौटाने पड़ते हैं; 64-बिट प्रणालियों पर यह आमतौर पर 16 बाइट होता है।
#include <stdalign.h>
/* the strictest fundamental alignment */
size_t strict = alignof(max_align_t); /* often 16 */align_up युक्ति
किसी आकार को दो की घात वाले संरेखण के अगले गुणज तक पूर्णांकित करना एक प्रसिद्ध बिट युक्ति है: a - 1 जोड़ें, फिर निचले बिटों को मास्क से हटा दें।
यह तभी काम करता है जब a दो की घात हो, और सभी वास्तविक संरेखण ऐसे ही होते हैं।
static size_t align_up(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1);
}
/* align_up(13, 8) == 16, align_up(16, 8) == 16 */गणित को चलाकर सिद्ध करना
आइए चलने योग्य प्रोग्राम से align_up की जाँच करें। यह कई आकारों को 8 और 16 बाइट की सीमाओं तक ऊपर की ओर पूर्णांकित करके परिणाम दिखाता है।
#include <stdio.h>
#include <stddef.h>
static size_t align_up(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1);
}
int main(void) {
printf("%zu\n", align_up(13, 8)); /* 16 */
printf("%zu\n", align_up(16, 8)); /* 16 */
printf("%zu\n", align_up(1, 16)); /* 16 */
printf("%zu\n", align_up(33, 16)); /* 48 */
return 0;
}अनुरोधित आकारों को संरेखित करना
आवंटक के भीतर हर अनुरोध का पहला चरण अनुरोधित आकार को संरेखण तक ऊपर की ओर पूर्णांकित करना है। इससे यह सुनिश्चित होता है कि अगला ब्लॉक भी संरेखित होकर शुरू हो।
पैडिंग बाइट आंतरिक विखंडन होती हैं—सार्वभौमिक संरेखण की कीमत।
#define ALIGN 16
void *my_alloc(size_t size) {
size = align_up(size, ALIGN);
/* now find a block of this aligned size */
/* ... */
return NULL;
}पूरे ब्लॉक के पुनः उपयोग की समस्या
पिछली सीख में हमने छोटे अनुरोधों के लिए भी पूरा मुक्त ब्लॉक लौटा दिया था। 16-बाइट के अनुरोध के लिए 4000-बाइट का मुक्त ब्लॉक देने से बाकी स्थान व्यर्थ जाता है।
विभाजन ब्लॉक को हमारे उपयोग वाले हिस्से और मुक्त रहने वाले शेष हिस्से में बाँट देता है।
एक ब्लॉक को विभाजित करना
यदि चुना हुआ ब्लॉक आवश्यकता से बहुत बड़ा हो, तो हम अनुरोधित क्षेत्र के अंत में एक नया शीर्षलेख रखते हैं। बचा हुआ हिस्सा सूची में एक छोटे मुक्त ब्लॉक में बदल जाता है।
हम तभी विभाजन करते हैं, जब शेष हिस्सा शीर्षलेख और कुछ पेलोड को रखने के लिए पर्याप्त बड़ा हो; अन्यथा वह टुकड़ा बेकार है।
void split(block_t *b, size_t size) {
size_t rem = b->size - size;
if (rem < sizeof(block_t) + ALIGN) return; /* too small */
block_t *nb = (block_t *)((char *)(b + 1) + size);
nb->size = rem - sizeof(block_t);
nb->free = 1;
nb->next = b->next;
b->size = size;
b->next = nb;
}आवंटन, संरेखण और विभाजन
अब आवंटन की पूरी प्रक्रिया आकार को संरेखित करती है, उपयुक्त ब्लॉक ढूँढती है, किसी भी बड़े शेष हिस्से को अलग करती है और ब्लॉक को उपयोग में चिह्नित करती है।
इससे ब्लॉक अपने आवश्यक आकार के बने रहते हैं और पीछे उपयोग योग्य मुक्त स्थान बचता है।
void *my_alloc(size_t size) {
size = align_up(size, ALIGN);
block_t *b = first_fit(size);
if (!b) return NULL;
split(b, size);
b->free = 0;
return (void *)(b + 1);
}पूल को स्वयं संरेखित रखना
शुद्धता के लिए पूल का प्रारंभिक पता और शीर्षलेख का आकार भी संरेखण का पालन करना चाहिए, ताकि हर पेलोड किसी सीमा पर स्थित हो।
स्थिर बफ़र पर alignas का उपयोग करने से पूरी व्यवस्था संरेखित होकर शुरू होती है।
#include <stdalign.h>
alignas(16) static unsigned char pool[4096];
/* pool now begins on a 16-byte boundary */चलने योग्य संरेखित आवंटन
यह प्रोग्राम एक संरेखित पूल से आवंटन करता है और लौटाए गए पते का 16 से शेषफल दिखाता है। शेषफल हमेशा शून्य होता है, अर्थात पता उचित रूप से संरेखित है।
#include <stdio.h>
#include <stddef.h>
#include <stdalign.h>
static size_t align_up(size_t n, size_t a){ return (n+a-1)&~(a-1); }
alignas(16) static unsigned char pool[1024];
static size_t off = 0;
void *alloc16(size_t s){ off=align_up(off,16); if(off+s>sizeof(pool)) return NULL; void*p=&pool[off]; off+=s; return p; }
int main(void){
void *a = alloc16(1);
void *b = alloc16(20);
printf("a %% 16 = %lu\n", (unsigned long)((size_t)a % 16));
printf("b %% 16 = %lu\n", (unsigned long)((size_t)b % 16));
return 0;
}विभाजन बनाम संयोजन
विभाजन और संयोजन एक-दूसरे के विपरीत हैं और एक-दूसरे का संतुलन बनाए रखते हैं। आवंटन बड़े ब्लॉकों को छोटे हिस्सों में विभाजित करता है; मुक्त करना छोटे ब्लॉकों को फिर से जोड़ता है।
साथ मिलकर, ये दोनों एक ही पूल को अनुरोधों के बदलते आकारों के लिए उपयोग करने देते हैं, बिना स्थान लीक किए या स्थायी रूप से विखंडित हुए।
खिलौना आवंटक से वास्तविक आवंटक तक
अब आपके पास सभी चार आधार-स्तंभ हैं: स्मृति का स्रोत, संरेखित शीर्षलेख, संयोजन सहित मुक्त-सूची पुनः उपयोग और विभाजन। वास्तविक आवंटक गति और बड़े पैमाने के लिए आकार-वर्ग बिन, थ्रेड कैश और OS एकीकरण जोड़ते हैं।
लेकिन यहाँ बनाए गए मूल विचार हर malloc कार्यान्वयन को शक्ति देते हैं।
त्वरित जाँच
विचार करें कि आवंटन के दौरान ब्लॉकों को क्यों विभाजित किया जाता है।
पुनरावलोकन
संरेखण बिट युक्ति (n + a - 1) & ~(a - 1) से आकारों को ऊपर की ओर पूर्णांकित करता है, ताकि हर पेलोड किसी भी प्रकार के लिए उपयुक्त हो। विभाजन बड़े मुक्त ब्लॉकों को एक उपयोग किए गए हिस्से और एक मुक्त शेष हिस्से में काटता है, जबकि संयोजन मुक्त करने पर इस प्रक्रिया को उलट देता है।
ये चारों आधार-स्तंभ मिलकर एक पूर्ण और सही स्मृति आवंटक बनाते हैं।
एआई शिक्षक के साथ C सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 39
- पाठ
- 144
अक्सर पूछे जाने वाले प्रश्न
क्या “Alignment और Splitting” पाठ निःशुल्क है?
हाँ—“Alignment और Splitting” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और C Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। C Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“Alignment और Splitting” में मैं क्या सीखूँगा?
ब्लॉक को उपयोग योग्य और व्यवस्थित बनाएँ। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ C Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या C Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर C Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 4वाँ पाठ है।
“Alignment और Splitting” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस C Academy पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर C Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- malloc कैसे काम करता है
- सरल Bump Allocator
- Free Lists और पुनः उपयोग
- Alignment और Splitting