आप आवंटित नहीं की गई स्मृति पर free
कॉल करने के लिए अनुमति नहीं है, मानक कहा गया है कि काफी स्पष्ट रूप (थोड़ा दूसरे शब्दों में बयान, मेरे जोर):
free
समारोह अंतरिक्ष के लिए द्वारा अपने तर्क पुनः आवंटित की जाती किए जाने की ओर इशारा का कारण बनता है, यानी, आगे आवंटन के लिए उपलब्ध कराया गया है। यदि तर्क एक शून्य सूचक है, तो कोई कार्रवाई नहीं होती है। अन्यथा, अगर तर्क किसी स्मृति प्रबंधन फ़ंक्शन द्वारा लौटाए गए पॉइंटर से मेल नहीं खाता है, या यदि किसी कॉल द्वारा खाली या पुनर्विक्रय करने के लिए स्थान को हटा दिया गया है, तो व्यवहार अपरिभाषित है।
उदाहरण के लिए, तो क्या होता है, अगर पता कर रहे हैं डबल-मुक्त एक नए ब्लॉक के बीच और कोड है कि यह आवंटित में पुनः आवंटन किया गया है सिर्फ वहाँ कुछ है कि एक असली malloc की तरह दिखाई देता स्टोर करने के लिए हुआ हेडर को अवरुद्ध करें? पसंद:
+- New pointer +- Old pointer
v v
+------------------------------------+
| <Dodgy bit> |
+------------------------------------+
कैओस, यही है।
मेमोरी आवंटन फ़ंक्शन एक श्रृंखला के समान उपकरण हैं और बशर्ते आप उन्हें सही तरीके से उपयोग करें, आपको कोई समस्या नहीं होनी चाहिए। आप उन्हें दुरुपयोग अगर, हालांकि, परिणाम अपनी खुद की गलती है, या तो भ्रष्ट स्मृति या बुरा, या अपनी बाहों में से एक को काटने :-)
और के बारे में टिप्पणी कर रहे हैं:
.. यह दोगुनी मुक्त स्थान के बारे में एंडुसर को गहराई से संवाद कर सकता है।
आप डबल-मुक्त एक ब्लॉक नहीं है सुनिश्चित करने के लिए malloc
और free
कॉल का एक रिकॉर्ड रखने के लघु, मैं इस व्यावहारिक होने के रूप में नहीं देख सकता। इसके लिए एक विशाल ओवरहेड की आवश्यकता होगी और अभी भी सभी समस्याओं को ठीक नहीं करेगा।
क्या होगा यदि:
- धागा एक आवंटित और पता 42
- धागा आबंटित स्मृति एक पते 42 पर स्मृति को मुक्त कर दिया और उसका उपयोग करना शुरू कर दिया।
- धागा ए ने स्मृति को दूसरी बार मुक्त कर दिया।
- थ्रेड सी आवंटित स्मृति को पता 42 और इसे उपयोग करना शुरू कर दिया।
आपके पास तब थ्रेड बी और सी दोनों सोचते हैं कि वे उस स्मृति के स्वामी हैं (इन्हें निष्पादन के धागे होने की आवश्यकता नहीं है, मैं यहां थ्रेड शब्द का उपयोग कर रहा हूं जैसे कि कोड का एक टुकड़ा चलता है - यह हो सकता है सभी निष्पादन के एक धागे में हो लेकिन अनुक्रमिक रूप से कहा जाता है)।
नहीं, मुझे लगता है कि वर्तमान malloc
और free
ठीक है, बशर्ते आप उन्हें सही तरीके से उपयोग करें। हर तरह से अपने स्वयं के संस्करण को लागू करने के लिए कुछ विचार दें, मुझे इसके साथ कुछ भी गलत नहीं लगता है, लेकिन मुझे संदेह है कि आप कुछ सुंदर कांटेदार प्रदर्शन मुद्दों में भाग लेंगे।
आपfree
चारों ओर अपने स्वयं के आवरण को लागू करना चाहते हैं हैं, तो आप विशेष रूप से नीचे myFreeXxx
कॉल की तरह कुछ के साथ, यह सुरक्षित (एक छोटे से प्रदर्शन हिट की कीमत पर) बना सकते हैं:
#include <stdio.h>
#include <stdlib.h>
void myFreeVoid (void **p) { free (*p); *p = NULL; }
void myFreeInt (int **p) { free (*p); *p = NULL; }
void myFreeChar (char **p) { free (*p); *p = NULL; }
int main (void) {
char *x = malloc (1000);
printf ("Before: %p\n", x);
myFreeChar (&x);
printf ("After: %p\n", x);
return 0;
}
कोड का नतीजा यह है कि आप अपने सूचक के सूचक के साथ myFreeXxx
कॉल कर सकते हैं और यह दोनों करेंगे:
- स्मृति मुक्त करें; और
- पॉइंटर को न्यूल पर सेट करें।
उस बाद का मतलब है कि, यदि आप पॉइंटर को फिर से मुक्त करने का प्रयास करते हैं, तो यह कुछ भी नहीं करेगा (क्योंकि मुक्त न्यूल मानक द्वारा कवर किया जाता है)।
यह सभी स्थितियों, से बचाने नहीं अगर आप कहीं और सूचक की एक प्रतिलिपि बनाने, मूल, नकल मुक्त जैसे तो मुक्त:
char *newptr = oldptr;
myFreeChar (&oldptr); // frees and sets to NULL.
myFreeChar (&newptr); // double-free because it wasn't set to NULL.
यदि आप ' सी 11 का उपयोग करने के लिए फिर से, प्रत्येक प्रकार के लिए एक अलग फ़ंक्शन को स्पष्ट रूप से कॉल करने से बेहतर तरीका है कि सी ने समय कार्य ओवरलोडिंग संकलित किया है। आप जबकि अभी भी प्रकार की सुरक्षा के लिए अनुमति देता है सही समारोह कॉल करने के लिए सामान्य चयन का उपयोग कर सकते हैं:
#include <stdio.h>
#include <stdlib.h>
void myFreeVoid (void **p) { free (*p); *p = NULL; }
void myFreeInt (int **p) { free (*p); *p = NULL; }
void myFreeChar (char **p) { free (*p); *p = NULL; }
#define myFree(x) _Generic((x), \
int** : myFreeInt, \
char**: myFreeChar, \
default: myFreeVoid )(x)
int main (void) {
char *x = malloc (1000);
printf ("Before: %p\n", x);
myFree (&x);
printf ("After: %p\n", x);
return 0;
}
इसी के साथ , तो आप बस myFree
फोन और यह प्रकार के आधार पर सही समारोह का चयन करेंगे।
क्या आप त्रुटि कोड कहां से एक कोड स्निपेट पोस्ट कर सकते हैं? – ChadNC
डाउनवोट क्यों? सुनिश्चित नहीं है कि यह एक डुप्ली है, लेकिन यह वास्तव में एक अच्छा सवाल है। –
सी एक ऐसी भाषा है जो गारंटीकृत सुरक्षा पर गति और प्रोग्रामर नियंत्रण को महत्व देती है। आपको उन आदतों को विकसित करने की उम्मीद है जो आपको यादृच्छिक चीजें करने और पकड़े जाने की उम्मीद करने के बजाए सुरक्षित रखेंगे।यहां तक कि यदि आप चाहते हैं कि बहीखाता करना संभव था, तो यह धीमा हो जाएगा, और मैं अन्य देवताओं को रखने के लिए गति मूल्य का भुगतान नहीं करना चाहता हूं (हम ब्रैकेट प्रकारों को ब्रेस करते हैं, यह सोचते हैं कि यह हमेशा अन्य देवताओं को सुरक्षा नेट की आवश्यकता है) सुरक्षित । –