खोज…


परिचय

गतिशील रूप से आबंटित स्मृति प्रबंध के लिए, मानक सी पुस्तकालय कार्य प्रदान करता malloc() , calloc() , realloc() और free() । C99 में और बाद में, aligned_alloc() भी है। कुछ प्रणालियाँ alloca() भी प्रदान alloca()

वाक्य - विन्यास

  • void * align_alloc (size_t alignment, size_t size); / * केवल C11 * / के बाद से
  • void * calloc (size_t nelements, size_t size);
  • शून्य मुक्त (शून्य * ptr);
  • शून्य * मॉलॉक (size_t आकार);
  • शून्य * realloc (शून्य * ptr, size_t आकार);
  • शून्य * एलोका (size_t आकार); / * alloca.h से, मानक नहीं, पोर्टेबल नहीं, खतरनाक। * /

पैरामीटर

नाम विवरण
आकार ( malloc , realloc और aligned_alloc ) बाइट्स में मेमोरी का कुल आकार। aligned_alloc लिए आकार संरेखण का एक अभिन्न aligned_alloc होना चाहिए।
आकार ( calloc ) प्रत्येक तत्व का आकार
nelements तत्वों की संख्या
ptr आबंटित स्मृति सूचक पहले द्वारा दिया malloc , calloc , realloc या aligned_alloc
संरेखण आवंटित स्मृति का संरेखण

टिप्पणियों

C11

ध्यान दें कि aligned_alloc() केवल C11 या बाद के लिए परिभाषित किया गया है।

POSIX पर आधारित सिस्टम जैसे संरेखित मेमोरी (जैसे posix_memalign() ) आवंटित करने के अन्य तरीके प्रदान करते हैं, और अन्य मेमोरी प्रबंधन विकल्प (जैसे mmap() ) भी हैं।

मुक्त स्मृति

फ्री () कॉल करके गतिशील रूप से आवंटित मेमोरी जारी करना संभव है।

int *p = malloc(10 * sizeof *p); /* allocation of memory */
if (p == NULL) 
{
    perror("malloc failed");
    return -1;
}

free(p); /* release of memory */
/* note that after free(p), even using the *value* of the pointer p
   has undefined behavior, until a new value is stored into it. */

/* reusing/re-purposing the pointer itself */
int i = 42;
p = &i; /* This is valid, has defined behaviour */

p द्वारा इंगित की गई मेमोरी को पुनः कॉल करने के बाद free() में libc कार्यान्वयन या अंतर्निहित OS द्वारा) पुनः प्राप्त किया जाता है, इसलिए p माध्यम से उस मेमोरी ब्लॉक को एक्सेस करने से अपरिभाषित व्यवहार को बढ़ावा मिलेगा। ऐसे पॉइंटर्स जो रेफरेंस मैमोरी एलीमेंट्स से मुक्त हुए हैं, आमतौर पर डैंगलिंग पॉइंटर्स कहलाते हैं, और एक सुरक्षा जोखिम पेश करते हैं। इसके अलावा, सी मानक बताता है कि यहां तक कि एक झूलने वाले सूचक के मूल्य तक पहुंचने के लिए अपरिभाषित व्यवहार होता है। ध्यान दें कि जैसा कि ऊपर दिखाया गया है पॉइंटर p को फिर से purposed किया जा सकता है।

कृपया ध्यान दें कि आप केवल कॉल कर सकते हैं free() संकेत दिए गए कि सीधे से लौटा दिए गए हैं पर malloc() , calloc() , realloc() और aligned_alloc() काम करता है, या जहां प्रलेखन आप स्मृति बताता आबंटित किया गया है कि जिस तरह से (कार्यों जैसे strdup () उल्लेखनीय उदाहरण हैं)। एक सूचक को मुक्त करना जो है,

  • एक चर पर & ऑपरेटर का उपयोग करके प्राप्त किया, या
  • एक आवंटित ब्लॉक के बीच में,

निषिद्ध है। ऐसी त्रुटि का आमतौर पर आपके संकलक द्वारा निदान नहीं किया जाएगा, लेकिन अपरिभाषित स्थिति में कार्यक्रम के निष्पादन का नेतृत्व करेंगे।

अपरिभाषित व्यवहार के ऐसे उदाहरणों को रोकने के लिए दो सामान्य रणनीतियाँ हैं।

पहला और श्रेयस्कर सरल है - p का अस्तित्व तभी है जब इसकी आवश्यकता नहीं है, उदाहरण के लिए:

if (something_is_needed())
{

    int *p = malloc(10 * sizeof *p);
    if (p == NULL) 
    {
        perror("malloc failed");
        return -1;
    }

    /* do whatever is needed with p */

    free(p);
}

सीधे ब्लॉक (यानी } ) के अंत से पहले free() कॉल करके, p खुद ही मौजूद है। कंपाइलर उसके बाद p का उपयोग करने के किसी भी प्रयास पर एक संकलन त्रुटि देगा।

एक दूसरा तरीका यह भी है कि यह जिस पॉइंट को मेमोरी रिलीज़ करता है, उसे रिलीज़ करने के बाद पॉइंटर को भी अमान्य कर दें:

free(p);
p = NULL;     // you may also use 0 instead of NULL

इस दृष्टिकोण के लिए तर्क:

  • कई प्लेटफार्मों पर, एक शून्य सूचक को निष्क्रिय करने का प्रयास तत्काल दुर्घटना का कारण होगा: सेगमेंटेशन दोष। यहां, हमें कम से कम एक स्टैक ट्रेस मिलता है जो उस चर की ओर इशारा करता है जिसे मुक्त होने के बाद इस्तेमाल किया गया था।

    NULL को पॉइंटर सेट किए बिना हमारे पास पॉइंटर को लटकाना है। कार्यक्रम बहुत संभावित रूप से दुर्घटनाग्रस्त हो जाएगा, लेकिन बाद में, क्योंकि सूचक बिंदुओं को स्मृति को भ्रष्ट कर दिया जाएगा। इस तरह के कीड़े का पता लगाना मुश्किल होता है क्योंकि वे एक कॉल स्टैक के परिणामस्वरूप हो सकते हैं जो प्रारंभिक समस्या से पूरी तरह से संबंधित नहीं हैं।

    इसलिए यह दृष्टिकोण असफल-तेज अवधारणा का अनुसरण करता है।

  • अशक्त सूचक को मुक्त करना सुरक्षित है। C मानक निर्दिष्ट करता है कि free(NULL) का कोई प्रभाव नहीं है:

    नि: शुल्क फ़ंक्शन के कारण ptr द्वारा इंगित की गई जगह को हटा दिया जाता है, अर्थात, आगे के आवंटन के लिए उपलब्ध कराया जाता है। यदि ptr एक शून्य सूचक है, तो कोई क्रिया नहीं होती है। अन्यथा, अगर तर्क एक सूचक से मेल नहीं खाता पहले से वापस लौटे calloc , malloc , या realloc समारोह, या अगर अंतरिक्ष के लिए एक कॉल द्वारा पुनः आवंटित की जाती किया गया है free या realloc , व्यवहार अपरिभाषित है।

  • कभी-कभी पहले दृष्टिकोण का उपयोग नहीं किया जा सकता है (जैसे मेमोरी एक फ़ंक्शन में आवंटित की जाती है, और एक पूरी तरह से अलग फ़ंक्शन में बहुत बाद में डीलॉक्लेट की जाती है)

मेमोरी आवंटित करना

मानक आवंटन

C डायनामिक मेमोरी एलोकेशन फ़ंक्शन <stdlib.h> हेडर में परिभाषित किए गए हैं। यदि कोई गतिशील रूप से किसी ऑब्जेक्ट के लिए मेमोरी स्पेस आवंटित करना चाहता है, तो निम्न कोड का उपयोग किया जा सकता है:

int *p = malloc(10 * sizeof *p);
if (p == NULL) 
{
    perror("malloc() failed");
    return -1;
}

इस बाइट की संख्या कि दस गणना करता int स्मृति में कब्जा है, तब से यह है कि कई बाइट्स का अनुरोध करता है malloc और प्रदान परिणाम (यानी, स्मृति हिस्सा है कि बस का उपयोग कर बनाया गया था के शुरू पते malloc ) एक सूचक नामित करने के लिए p

sizeof का उपयोग करने के लिए sizeof का उपयोग करना अच्छा अभ्यास है क्योंकि sizeof के परिणाम को परिभाषित करने के बाद से लागू किया जाता है ( चरित्र प्रकारों को छोड़कर, जो कि char , signed char और unsigned char signed char होते हैं , जिसके लिए sizeof को हमेशा 1 देने के लिए परिभाषित किया जाता है)।

क्योंकि malloc अनुरोध को सेवा देने में सक्षम नहीं हो सकता है, इसलिए यह अशक्त सूचक को वापस कर सकता है। बाद में अशक्त सूचक को रोकने के प्रयासों को रोकने के लिए इसके लिए जांच करना महत्वपूर्ण है।

malloc() का उपयोग करके मेमोरी को गतिशील रूप से आवंटित किया जा सकता है, जिसका उपयोग realloc() का उपयोग करके किया जा सकता है या, जब जरूरत नहीं हो, free() का उपयोग करके जारी किया जाता है।

वैकल्पिक रूप से, int array[10]; घोषित करना int array[10]; स्मृति की एक ही राशि आवंटित करेगा। हालाँकि, अगर इसे कीवर्ड static बिना किसी फ़ंक्शन के अंदर घोषित किया जाता है, तो यह केवल उस फ़ंक्शन के भीतर उपयोग करने योग्य होगा, जिसे यह घोषित किया गया है और यह फ़ंक्शन कॉल करता है (क्योंकि स्टैक पर सरणी आवंटित की जाएगी और पुन: उपयोग के लिए स्थान जारी किया जाएगा समारोह लौटता है)। वैकल्पिक रूप से, यदि इसे किसी फ़ंक्शन के अंदर static साथ परिभाषित किया गया है, या यदि इसे किसी फ़ंक्शन के बाहर परिभाषित किया गया है, तो इसका जीवनकाल कार्यक्रम का जीवनकाल है। पॉइंटर्स को एक फंक्शन से भी लौटाया जा सकता है, हालाँकि C में एक फंक्शन एक अरै वापस नहीं कर सकता।

जीरो मेमोरी

द्वारा दिया स्मृति malloc एक उचित मूल्य के लिए शुरू नहीं किया जा सकता है, और देखभाल के साथ स्मृति शून्य से लिया जाना चाहिए memset या तुरंत इसे में एक उपयुक्त मान की प्रतिलिपि करने के लिए। वैकल्पिक रूप से, calloc वांछित आकार का एक ब्लॉक लौटाता है, जहां सभी बिट्स को 0 प्रारंभ किया जाता है। यह फ़्लोटिंग-पॉइंट शून्य या अशक्त सूचक स्थिरांक के प्रतिनिधित्व के समान नहीं है।

int *p = calloc(10, sizeof *p);
if (p == NULL) 
{
    perror("calloc() failed");
    return -1;
}

पर एक नोट calloc : अधिकांश (आमतौर पर इस्तेमाल किया) कार्यान्वयन को अनुकूलित करेंगे calloc() प्रदर्शन के लिए, तो यह हो जाएगा तेजी से बुला से malloc() , तो memset() , भले ही शुद्ध प्रभाव समान है।

संरेखित मेमोरी

C11

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

/* Allocates 1024 bytes with 256 bytes alignment. */
char *ptr = aligned_alloc(256, 1024);
if (ptr) {
    perror("aligned_alloc()");
    return -1;
}
free(ptr);

C11 मानक दो प्रतिबंध लगाता है: 1) अनुरोधित आकार (दूसरा तर्क) संरेखण (प्रथम तर्क) का अभिन्न गुणक होना चाहिए और 2) संरेखण का मूल्य कार्यान्वयन द्वारा समर्थित एक मान्य संरेखण होना चाहिए। दोनों में से किसी एक को पूरा करने में असफल होने के कारण अपरिभाषित व्यवहार होता है

Reallocating मेमोरी

आपके द्वारा मेमोरी को आवंटित करने के बाद आपको अपने पॉइंटर स्टोरेज स्पेस को विस्तारित या सिकोड़ने की आवश्यकता हो सकती है। void *realloc(void *ptr, size_t size) फ़ंक्शन ptr द्वारा इंगित की गई पुरानी वस्तु को बताता है और एक पॉइंटर को एक ऑब्जेक्ट पर लौटाता है जिसका आकार आकार द्वारा निर्दिष्ट होता sizeptr पहले से आवंटित एक स्मृति ब्लॉक करने के लिए सूचक है malloc , calloc या realloc (या एक अशक्त सूचक) पुनः आवंटन किया जाना है। मूल मेमोरी की अधिकतम संभव सामग्री संरक्षित है। यदि नया आकार बड़ा है, तो पुराने आकार से परे कोई भी अतिरिक्त मेमोरी अनइंस्टाल्यूटेड है। यदि नया आकार छोटा है, तो सिकुड़े हुए भाग की सामग्री खो जाती है। यदि ptr NULL है, तो एक नया ब्लॉक आवंटित किया जाता है और इसे एक पॉइंटर फ़ंक्शन द्वारा वापस किया जाता है।

#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    int *p = malloc(10 * sizeof *p);
    if (NULL == p) 
    {
        perror("malloc() failed");
        return EXIT_FAILURE;
    }
 
    p[0] = 42;
    p[9] = 15;

    /* Reallocate array to a larger size, storing the result into a
     * temporary pointer in case realloc() fails. */
    {
        int *temporary = realloc(p, 1000000 * sizeof *temporary);

        /* realloc() failed, the original allocation was not free'd yet. */
        if (NULL == temporary)
        {
            perror("realloc() failed");
            free(p); /* Clean up. */
            return EXIT_FAILURE;
        }      

        p = temporary;
    }

    /* From here on, array can be used with the new size it was 
     * realloc'ed to, until it is free'd. */

    /* The values of p[0] to p[9] are preserved, so this will print:
       42 15
    */
    printf("%d %d\n", p[0], p[9]);

    free(p);

    return EXIT_SUCCESS;
}

वास्तविक वस्तु का पता *p जैसा नहीं हो सकता है। इसलिए realloc से रिटर्न वैल्यू पर कब्जा करना महत्वपूर्ण है जिसमें कॉल सफल होने पर नया पता होता है।

सुनिश्चित करें कि आप की वापसी मान असाइन बनाओ realloc एक करने के लिए temporary मूल के बजाय prealloc किसी भी विफलता के मामले में अशक्त हो जाएगा, जो सूचक को अधिलेखित कर देगा। इससे आपका डेटा खो जाएगा और मेमोरी लीक हो जाएगी।

चर आकार के बहुआयामी सरणियों

C99

चूंकि C99, C में वैरिएबल लेंथ एरे, VLA है, जो कि मॉडल को सीमा के साथ एरे करता है जिसे केवल आरंभीकरण समय पर जाना जाता है। जबकि आपको सावधान रहना होगा कि बहुत बड़े वीएलए को आवंटित न करें (वे आपके स्टैक को तोड़ सकते हैं), वीएलए को पॉइंटर्स का उपयोग करके और उन्हें sizeof अभिव्यक्तियों में उपयोग करना ठीक है।

double sumAll(size_t n, size_t m, double A[n][m]) {
    double ret = 0.0;
    for (size_t i = 0; i < n; ++i)
       for (size_t j = 0; j < m; ++j)
          ret += A[i][j]
    return ret;
}

int main(int argc, char *argv[argc+1]) {
   size_t n = argc*10;
   size_t m = argc*8;
   double (*matrix)[m] = malloc(sizeof(double[n][m]));
   // initialize matrix somehow
   double res = sumAll(n, m, matrix);
   printf("result is %g\n", res);
   free(matrix);
}

यहां matrix टाइप double[m] तत्वों के लिए एक संकेतक है, और double[n][m] साथ sizeof अभिव्यक्ति यह सुनिश्चित करती है कि इसमें n ऐसे तत्वों के लिए जगह हो।

इस सभी स्थान को आकस्मिक रूप से आवंटित किया गया है और इस प्रकार इसे एक कॉल से free लिए निपटाया जा सकता है।

भाषा में वीएलए की उपस्थिति फ़ंक्शन हेडर में सरणियों और संकेत की संभावित घोषणाओं को भी प्रभावित करती है। अब, सरणी मापदंडों के [] के अंदर एक सामान्य पूर्णांक अभिव्यक्ति की अनुमति है। दोनों कार्यों के लिए पैरामीटर सूची में पहले घोषित किए गए [] मापदंडों का उपयोग करें। sumAll ये लंबाई है कि उपयोगकर्ता कोड मैट्रिक्स के लिए उम्मीद करता है। सी में सभी फ़ंक्शन फ़ंक्शन मापदंडों के रूप में अंतरतम आयाम एक सूचक प्रकार को फिर से लिखा जाता है, इसलिए यह घोषणा के बराबर है

  double sumAll(size_t n, size_t m, double (*A)[m]);

यही है, n वास्तव में फ़ंक्शन इंटरफ़ेस का हिस्सा नहीं है, लेकिन जानकारी दस्तावेज़ीकरण के लिए उपयोगी हो सकती है और इसका उपयोग सीमाओं की जांच करने वाले कंपाइलरों द्वारा आउट-ऑफ-बाउंड एक्सेस के बारे में चेतावनी देने के लिए भी किया जा सकता है।

इसी तरह, main , अभिव्यक्ति argc+1 न्यूनतम लंबाई है जो C मानक argv तर्क के लिए निर्धारित करता है।

ध्यान दें कि आधिकारिक तौर पर वीएलए का समर्थन सी 11 में वैकल्पिक है, लेकिन हमें ऐसे संकलक के बारे में पता है जो C11 को लागू करते हैं और उनके पास यह नहीं है। यदि आप चाहिए तो आप मैक्रो __STDC_NO_VLA__ साथ परीक्षण कर सकते हैं।

realloc (ptr, 0) मुफ्त के बराबर नहीं है (ptr)

realloc वैचारिक रूप से दूसरे सूचक पर malloc + memcpy + free बराबर है।

यदि अनुरोधित स्थान का आकार शून्य है, तो realloc का व्यवहार कार्यान्वयन-परिभाषित है। यह सभी मेमोरी आवंटन कार्यों के लिए समान है जो मान 0 size पैरामीटर प्राप्त करते हैं। इस तरह के कार्य वास्तव में एक गैर-अशक्त पॉइंटर लौटा सकते हैं, लेकिन इसे कभी भी अस्वीकार नहीं किया जाना चाहिए।

इस प्रकार, realloc(ptr,0) free(ptr) बराबर नहीं है। यह शायद

  • एक "आलसी" कार्यान्वयन हो और बस ptr लौटें
  • free(ptr) , एक डमी तत्व आवंटित करें और उसे वापस करें
  • free(ptr) और वापसी 0
  • सिर्फ असफलता के लिए 0 वापस करें और कुछ न करें।

तो विशेष रूप से बाद के दो मामले आवेदन कोड द्वारा अप्रभेद्य हैं।

इसका मतलब यह है कि realloc(ptr,0) मेमोरी को वास्तव में खाली नहीं कर सकता / सकती है, और इस प्रकार इसे कभी भी free बदलने के रूप में उपयोग नहीं किया जाना चाहिए।

उपयोगकर्ता-परिभाषित स्मृति प्रबंधन

malloc() अक्सर मेमोरी के पृष्ठों को प्राप्त करने के लिए अंतर्निहित ऑपरेटिंग सिस्टम फ़ंक्शन को कॉल करता है। लेकिन फ़ंक्शन के बारे में कुछ भी विशेष नहीं है और इसे एक बड़े स्थैतिक सरणी की घोषणा करके और उससे आवंटित करके सीधे सी में लागू किया जा सकता है (सही संरेखण सुनिश्चित करने में थोड़ी कठिनाई होती है, अभ्यास में 8 बाइट्स को लगभग हमेशा पर्याप्त होता है)।

एक साधारण योजना को लागू करने के लिए, कॉल से वापस किए जाने वाले पॉइंटर से तुरंत पहले मेमोरी के क्षेत्र में एक नियंत्रण ब्लॉक संग्रहीत किया जाता है। इसका मतलब यह है कि free() पॉइंटर को लौटाए गए पॉइंटर से घटाकर और नियंत्रण सूचना को पढ़कर लागू किया जा सकता है, जो कि आमतौर पर ब्लॉक आकार और कुछ जानकारी है जो इसे मुफ्त सूची में वापस रखने की अनुमति देता है - बिना ब्लॉक वाले लिंक की एक सूची।

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

/* typical control block */
struct block
{
   size_t size;         /* size of block */
   struct block *next;  /* next block in free list */ 
   struct block *prev;  /* back pointer to previous block in memory */
   void *padding;       /* need 16 bytes to make multiple of 8 */
}

static struct block arena[10000]; /* allocate from here */
static struct block *firstfree;

कई कार्यक्रमों में समान आकार की छोटी वस्तुओं के आवंटन की बड़ी संख्या की आवश्यकता होती है। इसे लागू करना बहुत आसान है। बस अगले पॉइंटर के साथ एक ब्लॉक का उपयोग करें। इसलिए यदि 32 बाइट्स का ब्लॉक आवश्यक है:

union block
{
   union block * next;
   unsigned char payload[32];
}  

static union block arena[100];
static union block * head; 
void init(void)
{
    int i;
    for (i = 0; i < 100 - 1; i++)
        arena[i].next = &arena[i + 1];
    arena[i].next = 0; /* last one, null */
    head = &block[0];
}
 
void *block_alloc()
{
    void *answer = head;
    if (answer)
        head = head->next;
    return answer;
}

void block_free(void *ptr)
{
    union block *block = ptr;
    block->next = head;
    head - block;
}

यह योजना बेहद तेज और कुशल है, और स्पष्टता के एक निश्चित नुकसान के साथ इसे सामान्य बनाया जा सकता है।

alloca: स्टैक पर मेमोरी आवंटित करें

alloca : alloca का उल्लेख केवल alloca लिए यहां किया गया है। यह पूरी तरह से गैर-पोर्टेबल है (किसी भी सामान्य मानकों द्वारा कवर नहीं किया गया है) और इसमें कई संभावित खतरनाक विशेषताएं हैं जो इसे अनजान के लिए सुरक्षित नहीं बनाती हैं। आधुनिक सी कोड को इसे वेरिएबल लेंथ एरे (वीएलए) से बदलना चाहिए।

मैनुअल पेज

#include <alloca.h>
// glibc version of stdlib.h include alloca.h by default

void foo(int size) {
    char *data = alloca(size);
    /*
      function body;
    */
    // data is automatically freed
}

कॉलर के स्टैक फ्रेम पर मेमोरी आवंटित करें, लौटे पॉइंटर द्वारा संदर्भित स्थान स्वचालित रूप से 'डी' मुक्त होता है जब कॉलर फ़ंक्शन समाप्त होता है।

हालांकि यह फ़ंक्शन स्वचालित मेमोरी प्रबंधन के लिए सुविधाजनक है, इस बात से अवगत alloca कि बड़े आवंटन का अनुरोध करने से स्टैक ओवरफ़्लो हो सकता है, और आप alloca साथ आवंटित मेमोरी के साथ free उपयोग नहीं कर सकते हैं (जो स्टैक ओवरफ़्लो के साथ अधिक समस्या पैदा कर सकता है)।

इन कारणों से यह लूप के अंदर alloca का उपयोग करने की सिफारिश नहीं की जाती है और न ही एक पुनरावर्ती फ़ंक्शन।

और मेमोरी free कारण free तो आप पॉइंटर को फंक्शन रिजल्ट के रूप में नहीं दे सकते ( व्यवहार अपरिभाषित होगा )।

सारांश

  • malloc समान है
  • स्वचालित रूप से नि: शुल्क समारोह वापसी पर होगा
  • free , realloc कार्यों ( अपरिभाषित व्यवहार ) के साथ असंगत
  • सूचक को फ़ंक्शन परिणाम ( अपरिभाषित व्यवहार ) के रूप में नहीं लौटाया जा सकता
  • स्टैक स्पेस द्वारा सीमित आबंटन का आकार, जो (अधिकांश मशीनों पर) malloc() द्वारा उपयोग के लिए उपलब्ध ढेर स्थान की तुलना में बहुत छोटा है malloc()
  • एक ही फ़ंक्शन में alloca() और वीएलएएएस (चर लंबाई सरणियों) का उपयोग करने से बचें
  • alloca() malloc() et al जितना पोर्टेबल नहीं है

सिफ़ारिश करना

  • नए कोड में alloca() उपयोग न करें
C99

आधुनिक विकल्प।

void foo(int size) {
    char data[size];
    /*
      function body;
    */
    // data is automatically freed
}

यह काम करता है जहां alloca() करता है, और उन जगहों पर काम करता है जहां alloca() लूप के अंदर नहीं है, उदाहरण के लिए)। यह या तो C99 कार्यान्वयन या C11 कार्यान्वयन मान लेता है जो __STDC_NO_VLA__ को परिभाषित नहीं करता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow