प्रौद्योगिकी साझेदारी

C भाषां आद्यतः एव शिक्षन्तु ३३ - स्मृतिप्रबन्धनम् (१) .

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. मूलभूतस्थितिः
C भाषायाः स्मृतिप्रबन्धनं द्वयोः भागयोः विभक्तम् अस्ति : प्रणालीप्रबन्धनं प्रोग्रामर उपयोक्तृपुस्तिकाप्रबन्धनं च । प्रणाल्याः प्रबन्धितः स्मृतिः मुख्यतया फंक्शन् इत्यस्य अन्तः चराः (स्थानीयचराः) भवन्ति यदा फंक्शन् चालितं भवति तदा स्मृतिक्षेत्रस्य एषः भागः "stack area" भवति , प्रचालनतन्त्रं स्वयमेव स्मृत्याः अवरोहति । उपयोक्त्रा हस्तचलितरूपेण प्रबन्धिता स्मृतिः मुख्यतया चराः (वैश्विकचराः) सन्ति ये कार्यक्रमस्य चालनस्य सम्पूर्णप्रक्रियायां विद्यन्ते यत्र एषः भागः स्थितः सः स्मृतिक्षेत्रं "ढेरक्षेत्रम्" इति कथ्यते प्रयोक्तृणा । यदि भवान् उपयोगानन्तरं तत् मुक्तुं विस्मरति तर्हि यावत् कार्यक्रमस्य निर्गमनसमये तत् प्रचालनतन्त्राय न समर्पितं तावत् स्मृतिं व्याप्य एव तिष्ठति ।
2. शून्यसूचकः
सङ्गणके स्मृतिस्थानं अद्वितीयं पतासङ्केतं नियुक्तं भवति, निर्दिष्टं स्मृतिक्षेत्रं स्मृतिसूचकद्वारा द्रष्टुं शक्यते । सूचकचरानाम् एकः प्रकारः आवश्यकः, उदाहरणार्थं: int* p=&x; दत्तांशः संगृह्यते । यदा भवान् निश्चितः नास्ति यत् किं प्रकारस्य दत्तांशः संगृहीतः अस्ति तथा च केवलं प्रथमं block memory address अन्वेष्टुम् इच्छति तदा void type pointer इत्यस्य उपयोगः भवति । शून्यप्रकारस्य सूचकः अनिश्चितप्रकारस्य सूचकः अपि उच्यते, सः कस्यापि प्रकारस्य दत्तांशं सूचयितुं शक्नोति ।
void प्रकारस्य सूचकाः अन्यप्रकारस्य सूचकाः परिवर्तयितुं शक्यन्ते, तेषां उपयोगे च किमपि विशेषं नास्ति, केवलं संगृहीतसामग्री "*" पद्धत्या विश्लेषणं कर्तुं न शक्यते
int x = 10 //पूर्णांक चर x घोषित करें
void* p = &x; //शून्यसूचकं घोषयन्तु तथा x इत्यस्य पतां दर्शयन्तु, यत् सूचयति यत् int सूचकः (&x) शून्यसूचकरूपेण परिवर्तितः अस्ति ।
int* q = p; // void सूचकं पुनः पूर्णाङ्कसूचकं प्रति परिवर्तितं भवति
printf( "% in", * q ); //परिणाम चलाओ: 10
void* तथा void इत्येतयोः मध्ये भेदं प्रति ध्यानं ददातु: void इति प्रकाररहितं भवति, तथा च यदा फंक्शन् घोषयितुं प्रयुक्तं भवति तदा तस्य अर्थः भवति यत् void*, यद्यपि टंकरहितः अस्ति परन्तु सूचकः अस्ति, तथापि किमपि प्रत्यागच्छति
3. स्मृतिप्रबन्धनसम्बद्धानि कार्याणि
१、मल्लोक्() २.
एतत् कार्यं पृथक् स्मर्तुं शक्यते m स्मृतेः संक्षिप्तनाम, alloc च आवंटनस्य संक्षिप्तनाम अस्ति ।
कार्यम्: ढेरक्षेत्रात् निरन्तरस्मृतिखण्डस्य कृते आवेदनं कुर्वन्तु (स्मरणं: ढेरक्षेत्रस्मृतिं प्रोग्रामरेण प्रबन्धयितुं आवश्यकं भवति तथा च उपयोगानन्तरं नष्टं कर्तव्यम्। एतत् सर्वदा स्मर्तव्यं: malloc (1 पश्यन्तु)
पैरामीटर्: पैरामीटर् 1 स्मृतिखण्डस्य आकारः अस्ति (size_t प्रकारस्य अऋणात्मकः पूर्णाङ्कः, sizeof इत्यस्य रिटर्न् मूल्यम् अस्य प्रकारस्य अस्ति)
Return value: void* pointer (आवंटितस्मृतिं प्राप्तुं वयं यस्य प्रकारस्य सूचकस्य उपयोगं कुर्मः तस्य उपयोगं करिष्यामः)
उपयोगः : malloc फंक्शन् इत्यस्य उपयोगेन घोषिताः चराः heap क्षेत्रे सन्ति, अतः अनामघोषणाविधिः प्रायः उपयुज्यते, अर्थात् विशिष्टचरानाम् address मेथड् इत्यस्य उपयोगस्य स्थाने malloc प्रत्यक्षतया सूचकं प्रत्यागच्छति, यथा अधः दर्शितम् अस्ति
int* ptr = (int*) malloc(sizeof(int)); //एकं int सूचकचरं ढेरक्षेत्रे घोषितं भवति
कोष्ठकेषु बलात् रूपान्तरणं आवश्यकं नास्ति, यत् int* इत्यनेन सह प्राप्तुं शक्यते ।
सावधानताः : १.
क. समावेशार्थं malloc फंक्शन् इत्यस्य उपयोगं कुर्वन्तु<stdlib.h>header file, यथा केवलं समाविष्टम्<stdio.h> इदं सम्यक् संकलितं करोति परन्तु सम्यक् न चालयति, तत् मनसि धारयन्तु ।
ख. ptr कृते मूल्यं नियुक्तं कुर्वन्तु: *ptr=1000;.
c. free (यस्य भवन्तः पश्चात् सम्मुखीभवन्ति) इत्यनेन सह malloc इत्यस्य उपयोगं कुर्वन्तु;.
d. Malloc पता आवंटने सफलः न भवेत् यदि असफलः भवति तर्हि अस्य कारणात् प्रसंस्करणार्थं if कथनं योजयितुं शक्यते ।
e. malloc केवलं स्मृतिम् आवंटयति, आरम्भीकरणस्य परवाहं न कृत्वा यदि आरम्भीकरणस्य आवश्यकता भवति तर्हि अन्यत् कार्यं आह्वयितुं आवश्यकम् ।
f. malloc कृते सर्वाधिकं प्रयुक्तः अवसरः सरणीनां तथा कस्टम् डाटा संरचनानां कृते स्मृतिः आवंटयितुं भवति ।
२、 मेम्सेट् () २.
कार्यम् : सूचकेन सूचिते स्मृतिखण्डे प्रत्येकं बाइट् कृते प्रारम्भिकं मूल्यं नियुक्तं कुर्वन्तु ।
पैरामीटर्: पैरामीटर् 1 लक्ष्यस्मृतिं प्रति सूचयति सूचकः पैरामीटर् 2 असाइनमेण्ट् सामग्री (int प्रकारः ASCII कोडमूल्यं वा char प्रकारस्य वर्णः) पैरामीटर् 3 असाइन कर्तव्यानां बाइट्-सङ्ख्या (size_t प्रकारः)
Return value: लक्ष्यस्मृतौ सूचितं सूचकं प्रत्यागच्छति, प्राप्तुं निरर्थकम् अस्ति, पैरामीटर् 1 इत्यस्य समानम् ।
उपयोगः: memset(ptrDestMem,'A',sizeof(char)*1024) //1024 बाइट् दीर्घतायाः स्मृतिखण्डस्य प्रत्येकं बाइट् कृते A वर्णं नियुक्तं कुर्वन्तु
सावधानताः : १.
a. यस्य शीर्षकसञ्चिकायाः ​​अयं कार्यः अन्तर्भवति सः अस्ति<string.h> , केचन संकलकाः सामान्यतया एतां शीर्षकसञ्चिकां न समाविष्ट्य उपयोक्तुं शक्यन्ते यदि चालनदोषः भवति तर्हि कृपया तत् समावेशयन्तु ।
ख.
c. पैरामीटर् 2 इत्यस्य मूल्यं एकेन बाइट् (int type 255) इत्यनेन समायोजितुं शक्यते इति अतिक्रमितुं न शक्नोति यदि मूल्यं अतिक्रमति तर्हि तत् लिखितुं न शक्यते ।
२、मुक्त() २.
कार्यम् : malloc इत्यनेन सह युग्मितं कार्यं, malloc फंक्शन् द्वारा आवंटितस्मृतिं मुक्तुं स्मृतिलीकं निवारयितुं च उपयुज्यते
पैरामीटर्स्: malloc फंक्शन् द्वारा प्रत्यागतः सूचकः
उपयोग: मुक्त (ptr);
सावधानताः : १.
क. मुक्तस्य उपयोगं कुर्वन् ये शीर्षकसञ्चिकाः समाविष्टाः भवेयुः ते अपि सन्ति<stdlib.h> , मा विस्मरतु ।
ख. मुक्तकार्यं एकवारमेव निष्पादयितुं शक्यते, तथा च समानं स्मृतिसङ्केतं पुनः पुनः मुक्तुं न शक्यते, मुक्तं सूचकं पुनः उपयोक्तुं न शक्यते ।
ग. प्रथमं malloc तथा free इति युग्मरूपेण लिखितुं श्रेयस्करम्, ततः विस्मरणं न भवेत् इति मध्ये अन्ये कोड्स् निवेशयितुं शक्यते ।
३、पुनः आवंटन() २.
पुनः अर्थात् पुनः आवंटनसंक्षेपः, एकत्र स्मृतेः पुनः आवंटनम् इति अर्थः
कार्यम् : आवंटितस्मृतिखण्डस्य आकारं परिवर्तयन्तु (वर्धनं न्यूनीकर्तुं वा)।
पैरामीटर्: पैरामीटर् 1, मूलस्मृतिखण्डसूचकः, पैरामीटर् 2, वर्धनस्य अथवा न्यूनीकरणस्य अनन्तरं स्मृतिखण्डस्य आकारः (अद्यापि size_t प्रकारः)
मूल्यं प्रत्यागच्छति: void* सूचकः (मूलसूचकप्रकारस्य चरेन प्राप्तुं शक्यते)
उपयोग: शून्य * newPtr = realloc (ptr, आकार (int) * 10);
सावधानताः : १.
a. realloc फंक्शन् इत्यस्य उपयोगं कुर्वन् तस्य अपि समावेशः आवश्यकः<stdlib.h> .

c.
4. अनुप्रयोगस्य उदाहरणानि

  1. #include<stdio.h>
  2. #include<stdlib.h> //malloc、free、realloc
  3. #include<string.h> //memset
  4. int main(void)
  5. {
  6. //A void指针的使用
  7. float PI = 3.14159;
  8. void* pPI = &PI;
  9. float r = 2.5;
  10. printf("半径2.5圆的面积:%fn", r * r * *(float*)pPI);//*(float*)pPI—pPI强转为float指针后再解出指向的值
  11. //B malloc、memset、free函数使用
  12. int n = 8;
  13. void* pMyMem = malloc(sizeof(char)*n); //char占1字节,malloc分派n字节的内存,返给void指针
  14. if (pMyMem == NULL)return 0; //若分派内存失败,程序结束
  15. void* myMem2=memset(pMyMem,'B',sizeof(char)*8); //对malloc分派的内存区块个字节都写入字符'B'。
  16. //并用myMem2接收返回的指针
  17. if (pMyMem == myMem2)printf("memset写入区块指针与其返回的指针相同n");
  18. char* transCh = pMyMem; //将void指针转成char型指针
  19. printf("显示写入内容:");
  20. for (int i = 0; i < n; i++)
  21. {
  22. printf("%c ", *transCh); //显示写入的字符
  23. transCh++;
  24. }
  25. printf("n");//换行
  26. free(pMyMem); //释放malloc函数分派的内存
  27. //free(ch); //只有malloc分派的内存才需要释放,且只释放一次(这里会报错)
  28. //C realloc、free函数的使用
  29. int* pMem = malloc(sizeof(int)*5);
  30. if (pMem == NULL)return 0;
  31. for (int i = 0; i < 5; i++) pMem[i] = (i+1)*10;
  32. for (int i = 0; i < 5; i++) printf("%i ", pMem[i]);
  33. printf("n重新增加分派内存后n");
  34. int* newpMem = realloc(pMem, sizeof(int) * 10);
  35. if (newpMem == NULL)return 0;
  36. for (int i = 0; i < 10; i++) newpMem[i] = (i + 1) * 10;
  37. for (int i = 0; i < 10; i++)printf("%i ", newpMem[i]);
  38. free(newpMem); //释放realloc的内存
  39. //free(pMem);//pMem已被重置,不能再释放,此语句会造成运行失败
  40. getchar(); //暂停屏幕
  41. return 0;
  42. }