क्या मुफ्त (ptr) जहां ptr पूर्ण भ्रष्ट मेमोरी है?


112

सैद्धांतिक रूप से मैं ऐसा कह सकता हूं

free(ptr);
free(ptr); 

एक स्मृति भ्रष्टाचार है क्योंकि हम उस स्मृति को मुक्त कर रहे हैं जिसे पहले ही मुक्त किया जा चुका है।

पर क्या अगर

free(ptr);
ptr=NULL;
free(ptr); 

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

क्या एक NULL पॉइंटर को वैध बनाना है?


1
C मुक्त मानक के बारे में निश्चित नहीं है, लेकिन C ++ डिलीट (NULL) पूरी तरह से वैध है, इसलिए मुझे लगता है कि मुफ्त (NULL) भी होना चाहिए।
प्रियांक बोलिया

14
@Pryank: delete NULLC ++ में मान्य नहीं है। हटाने को ठोस प्रकार के शून्य-पॉइंटर मानों पर लागू किया जा सकता है, लेकिन नहीं NULLdelete (int*) NULLकानूनी है, लेकिन नहीं delete NULL
चींटी

तो इसका मतलब है कि अगर कोई सूचक NULL को इंगित कर रहा है तो कुछ भी प्रदर्शन नहीं करता है। इसका मतलब है कि !!!!!! हमारी कोडिंग में हर बार अगर कोई मेमोरी मुक्त करना चाहता है तो बस एक मुफ्त (ptr) को ptr = NULL से बदल सकता है?
विजय

3
नहीं, यदि ptrस्मृति को इंगित करता है, और आप उस freeपर कॉल नहीं करते हैं , तो मेमोरी लीक हो जाएगी। NULLबस इसे सेट करने से मेमोरी पर आपका हैंडल खो जाता है, और लीक हो जाता है। यदि ptr ऐसा होता हैNULL , तो कॉलिंग freeएक संचालन नहीं है।
GManNickG

1
@बेनजामिन: हुह? क्या निष्कर्ष निकाला है कि आप के free(ptr)साथ बदल सकते हैं ptr = NULL। किसी ने भी ऐसा कुछ नहीं कहा।
चींटी

जवाबों:


224

7.20.3.2 free फ़ंक्शन

सार

#include <stdlib.h> 
void free(void *ptr); 

विवरण

freeसमारोह अंतरिक्ष के लिए द्वारा बताया कारण बनता है ptrपुनः आवंटित की जाती हो सकता है, कि है, आगे आवंटन के लिए उपलब्ध कराया। यदि ptrकोई नल सूचक है, तो कोई क्रिया नहीं होती है।

आईएसओ-आईईसी 9899 देखें ।

यह कहा जा रहा है, जब जंगली में विभिन्न कोडबेस को देखते हैं, तो आप कभी-कभी लोगों को नोटिस करेंगे:

if (ptr)
  free(ptr);

ऐसा इसलिए है क्योंकि कुछ सी रनटाइम (मुझे यकीन है कि यह पामओएस पर मामला था याद है) एक NULLपॉइंटर को मुक्त करने पर दुर्घटनाग्रस्त हो जाएगा ।

लेकिन आजकल, मेरा मानना ​​है कि यह मान free(NULL)लेना सुरक्षित है कि मानक के अनुसार निर्देश दिया गया है।


29
नहीं, ptr = NULL कोई रास्ता नहीं है जो मुफ्त में उपलब्ध है (ptr), दोनों बिल्कुल अलग हैं
प्रसून सौरव

7
नहीं, इसका मतलब है free(ptr)कि ptrअशक्त का कोई दुष्प्रभाव नहीं है। लेकिन किसी भी स्थिति में, प्रत्येक मेमोरी का उपयोग करके आवंटित किया गया है malloc()या calloc()बाद में जारी किया जाना चाहिएfree()
ग्रेगरी पकोस्ज़

4
ptr = NULL यह सुनिश्चित करता है कि अगर आप गलती से भी मुफ्त में कॉल करें (ptr) तो आपका प्रोग्राम segfault नहीं करेगा।
प्रसून सौरव

2
कृपया ध्यान दें कि यद्यपि C मानक कहता है कि यह एक नो-ऑप है, लेकिन इसका मतलब यह नहीं है कि प्रत्येक सी-लाइब्रेरी इसे उसी तरह से संभालती है। मैंने मुफ्त (NULL) के लिए क्रैश देखा है, इसलिए पहली जगह में मुफ्त कॉल करने से बचना सबसे अच्छा है।
डेरिक

6
@WereWolfBoy वह बुला से पहले free(NULL)सूचक के परीक्षण से बचने का मतलब हैNULLfree()
ग्रेगरी Pakosz

22

सी लाइब्रेरी के सभी मानकों के अनुरूप संस्करण मुफ्त (NULL) को नो-ऑप मानते हैं।

उस ने कहा, एक समय में मुफ्त के कुछ संस्करण थे जो मुफ्त (NULL) पर दुर्घटनाग्रस्त हो जाएंगे, यही वजह है कि आप कुछ रक्षात्मक प्रोग्रामिंग सलाह देख सकते हैं:

if (ptr != NULL)
    free(ptr);

8
-1 [उद्धरण वांछित]। एक पुरातन श्रवण कार्यान्वयन के कुछ सिद्धांत के कारण कोड-शैली को बदलना एक बुरा विचार है।
टॉमस

41
@ टॉमास - मैंने कभी भी बदलती शैली की सिफारिश नहीं की, मैंने बस समझाया कि क्यों आप अभी भी कुछ शैलियों में यह सिफारिश देख सकते हैं।
आर सैमुअल क्लैचको

5
@ टोमस 3BSD ( winehq.org/pipermail/wine-patches/2006-October/031544.html ) और पामओएस फॉर टू (दोनों के लिए दूसरा हाथ)।
डगलस लीडर

7
@ टॉमास: समस्या संस्करण 7 यूनिक्स जैसी चीजों में थी। जब मैं सीख रहा था, तो मुफ्त (xyz) जहां xyz == NULL मशीन पर तत्काल आपदा के लिए एक नुस्खा था जहां मैंने सीखा (ICL Perq रनिंग PNX, जो कुछ सिस्टम III एक्स्ट्रा के साथ संस्करण 7 यूनिक्स पर आधारित था)। लेकिन मैं लंबे समय से उस तरह से कोड नहीं कर रहा हूं।
जोनाथन लेफ़लर

2
नेटवेयर फ्री-इन-
एनएलएल

13

यदि ptr NULL है, तो कोई भी ऑपरेशन नहीं किया जाता है।

प्रलेखन कहता है।


क्या आपका मतलब है कि कुछ भी नहीं किया जाएगा?
विजय

2
बेंजामिन, यही इसका मतलब है। यदि आप तर्क की अशक्तता के बारे में जानते हैं तो आप उससे क्या अपेक्षा करेंगे?
माइकल क्रेलिन - 7

12

मुझे याद है कि पामोस पर काम कर रहा था जहां free(NULL)दुर्घटनाग्रस्त हो गया।


4
दिलचस्प है - जो एक दूसरा प्लेटफॉर्म बनाता है (3BSD के बाद) जो दुर्घटनाग्रस्त हो जाता है।
डगलस लीडर

2
अगर मुझे सही से याद है, तो पाम पर सी स्टैंडर्ड लाइब्रेरी मौजूद नहीं थी। इसके बजाय, ज्यादातर असमर्थित हेडर फ़ाइल थी जो पाम ओएस एसडीके के माध्यम से मानक पुस्तकालय को मैप करती थी। बहुत सी चीजों ने अप्रत्याशित रूप से काम किया। NULLमानक लाइब्रेरी की तुलना में क्रैशिंग पाम टूलबॉक्स के बड़े चल रहे अंतरों में से एक था।
स्टीवन फिशर

8
free(ptr);
ptr=NULL;
free(ptr);/*This is perfectly safe */

आप एक NULL पॉइंटर को सुरक्षित रूप से हटा सकते हैं। उस स्थिति में कोई ऑपरेशन नहीं किया जाएगा। अन्य शब्दों में () एक पूर्ण सूचक पर कुछ भी नहीं करता है।


8

प्राप्त उपयोग:

free(ptr);
ptr = NULL;

देख:

man free

     The free() function deallocates the memory allocation pointed to by ptr.
     If ptr is a NULL pointer, no operation is performed.

जब आप पॉइंटर को सेट करने के NULLबाद फिर से उस पर free()कॉल कर सकते हैं free()और कोई ऑपरेशन नहीं किया जाएगा।


3
यह भी डिबगर के साथ segfaults को स्पॉट करने में मदद करता है। यह स्पष्ट है कि p-> do () पर p = 0 के साथ सेगफॉल्ट एक मुक्त सूचक का उपयोग कर रहा है। कम स्पष्ट है जब आप डिबगर में p = 0xbfade12 देखते हैं :)
न्यूरो

6

free(NULL)सी में पूरी तरह से कानूनी है delete (void *)0और delete[] (void *)0सी ++ में कानूनी हैं।

बीटीडब्ल्यू, मेमोरी को दो बार मुक्त करने से आमतौर पर किसी प्रकार की रनटाइम त्रुटि होती है, इसलिए यह कुछ भी भ्रष्ट नहीं करता है।


2
delete 0C ++ में कानूनी नहीं है। deleteस्पष्ट रूप से सूचक प्रकार की अभिव्यक्ति की आवश्यकता है। deleteटाइप किए गए नल-पॉइंटर मान पर लागू करना कानूनी है , लेकिन 0(और नहीं NULL)।
ए.टी.

1
आप void*या तो डिलीट नहीं कर सकते : P किस डिस्ट्रक्टर्स (s) को चलना चाहिए?
GManNickG

1
@ मन: जब तक यह अशक्त है, तब तक आप इसे हटा सकते हैंvoid *
चींटी

ठीक है पर्याप्त ठीक है। मैं भूल गया कि हम केवल विशेष रूप से अशक्त हैं।
GManNickG

आमतौर पर कुछ भी भ्रष्ट नहीं करता है, लेकिन इसकी गारंटी नहीं है। ASLR इसे बल्कि असंभाव्य बनाता है, लेकिन फिर भी असंभव नहीं है: buf1=malloc(X); free(buf1);buf2=malloc(X);free(buf1); - यहाँ यदि आप अशुभ हैं, तो buf2 को buf1 के समान सटीक पता मिला है, और आपने गलती से buf1 को दो बार मुक्त कर दिया है, इसलिए buf1 के 2 मुक्त पर आप वास्तव में buf2 को चुपचाप मुक्त करते हैं, बिना आवरण के। कोई (अपरिपक्व) त्रुटि / दुर्घटना / जो भी हो। (लेकिन आप अगली बार जब आप buf2 का उपयोग करने की कोशिश करेंगे तो शायद आपको एक दुर्घटना हो जाएगी - और यह परिदृश्य बहुत संभव नहीं है अगर आप ASLR पर चल रहे हैं)
hanshenrik

3

free(ptr)C में सेव ptrहै NULL, हालांकि, जो कि ज्यादातर लोग नहीं जानते, वह यह है कि NULL0. के बराबर की आवश्यकता नहीं है। मेरे पास एक अच्छा पुराना-स्कूल उदाहरण है: C64 पर, पता 0 पर, एक IO- पोर्ट है। यदि आपने इस पोर्ट तक पहुंचने के लिए C में एक प्रोग्राम लिखा है, तो आपको एक पॉइंटर की आवश्यकता होगी जिसका मूल्य 0. है। इसी C लाइब्रेरी को 0 और NULLउसके बीच अंतर करना होगा ।

सधन्यवाद।


दिलचस्प तथ्य, मुझे आश्चर्य से पकड़ा। मुझे NULL पॉइंटर प्रश्नों / उत्तरों के इर्द-गिर्द यात्रा करने के लिए मजबूर किया।
आर्थ्रोपोड


-3

ptr कुछ मेमोरी लोकेशन की ओर इशारा करता है, जो 0x100 कहता है।

जब आप फ्री (ptr), मूल रूप से आप 0x100 को मेमोरी मैनेजर द्वारा अन्य गतिविधि या प्रक्रिया के लिए उपयोग करने की अनुमति दे रहे हैं और सरल शब्दों में यह संसाधनों का बहिष्कार है।

जब आप ptr = NULL करते हैं, तो आप ptr को नए स्थान पर लाते हैं (यह जानने की चिंता नहीं करते हैं कि NULL क्या है)। ऐसा करने से आप 0x100 मेमोरी डेटा का ट्रैक खो देते हैं। यह मेमोरी लीक है।

इसलिए एक मान्य ptr पर ptr = NULL का उपयोग करना उचित नहीं है।

इसके बजाय आप कुछ सुरक्षित जांच कर सकते हैं:

अगर (ptr! = NULL) {मुफ्त (ptr);}

जब आप मुफ्त (ptr) जहां ptr पहले से ही NULL को इंगित कर रहे हैं, तो यह कोई ऑपरेशन नहीं करता है। तो, ऐसा करने के लिए सुरक्षित है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.