2011-05-11 5 views
5

मुझे धीरे-धीरे पॉइंटर्स का लटका मिल रहा है। लेकिन अभी भी मेरे कुछ प्रश्न हैं।सी शुरुआती प्रश्न: सूचक अंकगणित> एक बार पूरा होने के बाद सफाई करें

क्या पॉइंटर अंकगणित का उपयोग करते समय मेमोरी लीक का कारण बनना संभव है क्योंकि आप पॉइंटर इंगित करने की वास्तविक स्थिति को स्थानांतरित कर रहे हैं?

मेरा मतलब है, अगर मैं कहता हूं कि मैं चारों ओर एक स्ट्रिंग चार की प्रतिलिपि बनाने के लिए ऊपर की ओर गिनता हूं, तो क्या मुझे गिनने की आवश्यकता होगी ताकि सी "जानता है" जहां पॉइंटर इंगित करता था?

धन्यवाद फ्रैंक

+2

हाँ (हालांकि यह शायद जायेंगे * बैंग *, बजाय रिसाव स्मृति) ... सूचक ब्लॉक जब आप कॉल की शुरुआत को इंगित करने की जरूरत है मुफ्त – forsvarir

+2

यह केवल तभी मायने रखता है जब सूचक 'मॉलोक' कॉल का नतीजा था।आम तौर पर यदि आपको गतिशील रूप से आवंटित ब्लॉक के माध्यम से चलने की आवश्यकता है, तो आप दूसरे पॉइंटर चर का उपयोग करेंगे या एक सरणी अनुक्रमणिका का उपयोग करेंगे और मूल पॉइंटर चर को अनमोडिफाइड रखें। –

उत्तर

8

एक स्मृति रिसाव संभव है। free() हमेशा सूचक malloc() द्वारा दिया साथ बुलाया जाना चाहिए, तो हाँ अगर आप कुछ इस तरह करते हैं:

int* ptr = malloc(sizeof(int)); 
free(ptr + 1); 

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

+0

धन्यवाद समानता। जब आप प्रोग्राम बंद करते हैं, तो स्मृति रिसाव बनी रहेगी - मेरा मतलब यह है कि जब तक आप मशीन को पुनरारंभ नहीं करते तब तक यह चला जाता है? या यह आपके द्वारा उपयोग किए जा रहे ओएस पर निर्भर करता है? –

+0

@ फ्रैंक विला। प्रक्रिया समाप्त होने पर मेमोरी आपके ओएस द्वारा जारी की जानी चाहिए। तो आपको अपनी मशीन को पुनरारंभ करने की आवश्यकता नहीं है। वैसे भी यह हमेशा ओएस है जो स्मृति को छोड़ देता है, इसलिए शायद कुछ ओएस मौजूद है जो ऐसा नहीं करते हैं (मुझे उनमें से कोई भी नहीं पता)। मेमोरी लीक की समस्या यह है कि आपका चल रहा एप्लिकेशन इसकी तुलना में अधिक मेमोरी का उपभोग कर रहा है। – Heisenbug

+1

कुछ दिलचस्प चर्चा के लिए यह प्रश्न देखें http://stackoverflow.com/questions/2213627/when-you-exit-ac-plication-is-the-malloc-ed-memory-automatically- मुक्त – Joe

4

मेमोरी लीक गतिशील स्मृति आवंटन के साथ होता है। यदि आप पॉइंटर को एक हीप सेगमेंट में संग्रहीत करते हैं जिसे आपने आवंटित किया है और फिर उस पॉइंटर संदर्भ को संशोधित करें, तो हो सकता है कि आप पिछली आवंटित स्मृति को रिलीज़ नहीं कर पाएंगे।

आपको एक और सूचक का उपयोग करना चाहिए, और आवंटित स्मृति के प्रारंभिक संदर्भ रखना चाहिए। उदाहरण के लिए: जब malloc() या इसी तरह के कार्यों का उपयोग कर और बुला free() जब यह आवश्यक है नहीं

char *pointer = (char*)malloc (SIZE); /*alloc space for storing a string of size SIZE*/ 
char *pointer2 = pointer; 
int i; 
for (i = 0 ; i < SIZE ; i++){ 
     pointer2 += 1; 
     //you are modifying the second pointer so you always keep a reference to the allocated memory(pointer) 
} 

//now you can call free on your memory 
free(pointer); 
8

मेमोरी ढेर पर आवंटित किया जाता है। एक सूचक बस इतना है, स्मृति में स्थान के लिए एक सूचक। बाद में इसे मुक्त करने के लिए आपको आवंटित स्मृति की शुरुआत के पते को जानने की आवश्यकता है।

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

यदि आप सूचक के साथ झुकाव करना चाहते हैं, तो इसकी प्रतिलिपि लें और मूल सूचक को संशोधित न करें।

int *x = malloc(...); 
int *y = x; 

... pointer arithmetic with y 

free(x); 
+0

धन्यवाद जो, मुझे एक प्रति का उपयोग करके ऐसी चीजों को रोकने के विचार को पसंद है। –

1

आप गलत स्थान पर सूचक बिंदु होने से, सूचक अंकगणित के साथ मेमोरी लीक बना सकते हैं ताकि वहाँ नहीं रह गया है स्मृति का हिस्सा आप पर इंगित कर रहे थे के लिए किसी भी संदर्भ हैं।

यह एक स्मृति रिसाव है चाहे कोई भी डेटा malloc() या स्थैतिक रूप से आवंटित किया गया हो। मॉलोक() के साथ गतिशील मेमोरी लीक हालांकि खतरनाक हैं, जबकि स्थिर मेमोरी लीक हानिरहित हैं।

ध्यान दें कि सरणी के बाहर इंगित करना अनिर्धारित व्यवहार है: कुछ भी हो सकता है। विभिन्न सरणीओं पर इशारा करते हुए पॉइंटर्स पर पॉइंटर अंकगणित करना भी अपरिभाषित व्यवहार है।

अपरिभाषित व्यवहार के कुछ उदाहरण:

typedef struct 
{ 
    char array1 [6] = "hello"; 
    char array2 [6] = "world"; 
} HelloWorld_t; 


HelloWorld_t hw; 
const char* ptr = hw.array1; 
ptr += 6; /* undefined behavior, out of bounds of the original array */ 
puts(ptr); /* anything can happen here: the program may crash */ 
puts(array2 - 6); /* also undefined behavior */ 
संबंधित मुद्दे