2010-02-02 11 views
25
struct foo 
{ 
    int a; 
    int b; 
}; 

void* p = (void*)malloc(sizeof(struct foo)); 
((foo*)p)->a;//do something. 
free(p);//Is this safe? 
+1

क्या यह वैध सी भी है? क्या वह आकार (संरचना फू) नहीं होना चाहिए?:) –

+2

परिभाषा के अनुसार, 'मुक्त') '' void * 'मान के लिए न केवल ठीक है, सभी' मुक्त() 'कभी भी' शून्य * 'देखता है, इसलिए तकनीकी रूप से, सी में मुक्त सबकुछ' शून्य है * ':-) –

+0

@ डैनियल - यदि आप मुझसे पूछते हैं, तो यह 'संरचना foo * p = malloc (sizeof * p) होना चाहिए); लेकिन मुझे क्या पता चलेगा? –

उत्तर

31

हां।

malloc रिटर्न void * और void * लेता है, तो आपके डाले के कुछ व्यर्थ हैं, और आप हमेशा एक void * मुक्त कराने रहे हैं आप सूचक के कुछ अन्य प्रकार के साथ शुरू कर रहे हैं, भले ही।

5

हां - free शून्य के लिए एक सूचक लेता है, इसलिए जब आप इसे कॉल करते हैं, तो पॉइंटर किसी भी मामले में शून्य के लिए पॉइंटर को (निहित) डाला जाता है।

अपने कोड के बाकी काफी इसलिए सुरक्षित नहीं है:

void* p = (void*)malloc(sizeof(foo)); 

आप चाहिए नहीं malloc से वापसी (सी) में डाली। यह #include <stdlib.h>

3

हां भूलने की गलती को कवर कर सकता है। free के लिए समारोह प्रोटोटाइप भी है:

void free(void *ptr); 
13

हाँ, यह सुरक्षित है। स्मृति आवंटित करते समय, रनटाइम लाइब्रेरी प्रत्येक आवंटन के आकार का ट्रैक रखती है। जब आप नि: शुल्क कॉल करते हैं(), यह पता देखता है, और यदि उसे उस पते के लिए आवंटन मिलता है, तो स्मृति की सही मात्रा को मुक्त किया जाता है (वह ब्लॉक जो उस पते पर आवंटित किया गया था)।

2

शायद यह दृश्यों के पीछे होने वाले जादू के कारण सुरक्षित महसूस नहीं करता है। सी रनटाइम और/या ओएस स्वयं अपने आकार और स्थान सहित मॉलोक द्वारा लौटाई गई स्मृति को सक्रिय रूप से ट्रैक कर रहा है। हालांकि ऐसा लगता है कि आप एक टाइपलेस पॉइंटर को मुफ्त में वापस भेज रहे हैं(), वास्तव में आप किसी ऑब्जेक्ट का संदर्भ वापस भेज रहे हैं, मेमोरी मैनेजर सक्रिय रूप से ट्रैकिंग कर रहा है।

3

सी में यह पूरी तरह से सुरक्षित है क्योंकि कॉल करने के लिए कोई विनाशक नहीं हैं।

मेमोरी सिस्टम आवंटन के आकार का ट्रैक रखता है।

सी ++ में आपको नए प्रकार के एरे को हटाने के लिए हटाएं [] ऑपरेटर का उपयोग करने सहित, आपको उसी प्रकार को हटाना होगा।

यह सुनिश्चित करने के लिए कि विनाशकों को बुलाया जाता है।

0

हां, लेकिन आम तौर पर यह खराब डिजाइन का संकेत है। malloc() आमतौर पर बफर आवंटित करने के लिए प्रयोग किया जाता है (उसी आदिम प्रकार के बड़े सरणी) या ऑब्जेक्ट्स (आरंभ किए गए फ़ील्ड वाले structs)। दोनों मामलों में, malloc और एक मामले में, malloc और मैच में तो

unsigned char *rgba_buffer = malloc(width * hieght * 4); 
    /* use the buffer here */ 
    free(rgba_buffer); 

    BITSTREAM *bs = bitstream("bitfile.boin"); 
    /* use the bitstream here */ 
    destroy_bitstream(bs); 

    typedef struct 
    { 
    FILE *fp; 
    unsigned char ch; 
    int index; 
    } BITSTREAM; 


    BITSTREAM *bitstream(const char *filename) 
    { 
     BITSTREAM *bs = malloc(sizeof(BITSTREAM)); 
     bs->fp = fopen(filename "rb"); 
     /* etc */ 
     return bs; 
    } 

    void destroybitstream(BITSTREAM *bs) 
    { 
    if(bs) 
    { 
     if(bs->fp) 
      fclose(bs->fp); 
     free(bs); 
    } 
    } 

से मेल खाना चाहिए, अन्य आबंटित स्मृति दिया जाता है में, वहाँ भी माध्यमिक संसाधन हैं, और निर्माता और नाशक मैच। स्मृति के क्षेत्र को आवंटित करना दुर्लभ होना चाहिए, लेकिन यह नहीं पता कि इसका क्या उपयोग किया जाता है। और आपको आवंटन को अंतःस्थापित नहीं किया जाना चाहिए और अराजकता से मुक्त होना चाहिए।

आधुनिक सी ++ अद्वितीय पॉइंटर्स के साथ यह सब कस कर देता है जो ऑब्जेक्ट "स्वयं" है। जबकि आप शून्य के लिए एक अद्वितीय सूचक हो सकता है, यह बहुत दुर्लभ होगा।

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